how to not inherit some or all parent persistence attributes - java

As shown below, i have the object Car with 2 persistence attributes:
public class Car {
#Column(name = "COLOR")
protected String color;
#Column(name = "BRAND")
protected String brand;
}
All objects that extends from Car use the 2 attributes, but in some the them, i want to exclude one or all attributes.
For example:
public class SpecialCar extends Car{
//how to tell here that i don't want to have Brand column
}
Thx for help

If you do not want it in SpecialCar then, to me, it means, it should not be in Car at all. Can't you simply remove it from Car?

I think that this is answered allready here:
Disabling inherited method on derived class
I also think that is not possible, but they give you a nice trick

Related

Forcing Java attribute type in sub-class

I´ve got a question about inheritance/force certain value to an attribute in Java I am not sure about, even I spend a lot of time thinking about it. I will try to be as simple as possible.
So I´ve got an abstract class Foo, which has the Lombok annotation #Data:
#Data
public abstract class Foo{
private String id;
protected BoundType type;
public abstract void setBoundType(BoundType boundType);
}
Here is the enum BoundType:
public enum BoundType {
IN, OUT;
}
And I´ve got another two classes, InFoo and OutFoo that extend Foo. The boundType of InFoo should always be the enum type IN. On the other side, the boundType in OutFoo should always be the enum type OUT. For instance:
#Data
public class InFoo extends Foo{
public void setBoundType() {
//ALWAYS HAS TO BE BoundType.IN
}
}
How can I enforce this? Not sure how to design it. Thanks in advance.
Make sure the constructor sets the correct value for each subclass, and then make sure there's no setter, so that there's no way to alter the value.
Also, see this post Omitting one Setter/Getter in Lombok on how to omit the setter for the BoundType field.
The correct value should be set in the constructor of the subclasses:
public InFoo() {
boundType = BoundType.IN;
}
If it is necessary to use the setter pattern, you can perform a check, there:
public void setBoundType(BoundType boundType) {
if(boundType != BoundType.IN)
throw new IllegalArgumentException();
this.boundType = boundType; // This line is actually unnecessary
}

Using composition as a workaround for inheritance in realm (android)?

In my app, I am using realm as a database platform. Realm has been great thus far- super easy to use, make queries, etc.-though, I have two qualms with it that I am trying to work around.
1) Realm does not support inheritance in model object classes which extend RealmObject.
- I am wondering if any developers out there have used composition as a workaround to the inheritance issue and if its worked for them.
- In other words, say I have a class "car" which extends RealmObject and then I have other classes such as "honda", "toyota", etc. Does it make sense to make separate car objects for each of these which contain either a honda, toyota, etc.?
2) Realm only supports getters and setters in model object classes
- My current workaround for this is by creating static methods within the model object classes.
- In other words, say I want to modify a honda's color, I would call something such as, Honda.updateColor(honda, blue).
- ^ Is this sloppy, or is this essentially the only way to handle such methods.
Really any feedback would be great!
A workaround I've used (in a nutshell)
Composition + Interface inheritance would allow you to get some polymorphism benefits back to your realmObjects.
Some code demonstration
interface IPerson {
String getName();
}
class Person extends RealmObject implements IPerson {
String name;
#Override
public String getName() {
return name;
}
}
interface IWorker extends IPerson {
int getSalary();
}
class Worker extends RealmObject implements IWorker {
Person person;
int salary;
#Override
public String getName() {
return person.getName();
}
#Override
public int getSalary() {
return salary;
}
}
Note
PrimaryKeys unfortunately have to be duplicated.
Check this answer of mine to get more details about this workaround.

Subclass of abstract class can't see constructor

Spent some time pulling my hair out here. Seems black and white, but I just can't seem to get it to work. Did a lot of digging on top of what my classes have said about abstract classes in java, but to no avail.
What I'm trying to do: as part of an assignment (so no big hints please, unless it's my IDE or something), I'm making a customer class abstract, and then going ahead and making some subclasses from that. In this way the abstract class will be instantiated by creating a subclass that utilizes the abstract classes methods/properties. With me so far?
package customer;
abstract class Customer {
private String id;
private String name;
public Customer(String id, String name) {
this.id = id;
this.name = name;
}
//accessors
public double getDiscount(double amt) {
double discount = 0;
return discount;
}
public String getID() {
return this.id;
}
public String name() {
return this.name;
}
}
Abstract Customer class, seems all good, simple, easy. Now the solid subclass RetailCustomer
package customer;
public class RetailCustomer extends Customer {
private double rateOfDiscount = 0.04;
public RetailCustomer(String id, String name, double rate) {
super(id, name);
this.rateOfDiscount = rate;
}
//mutators
public void setDiscount(double rate) {
this.rateOfDiscount = rate;
}
//accessors
public double getDiscount() {
return this.rateOfDiscount;
}
}
Ok. Again, very simple. RetailCustomer extends Customer abstract class, and is supposed to make use of the abstract classes constructor, as seen with
public RetailCustomer(String id, String name, double rate) {
super(id, name);
this.rateOfDiscount = rate;
}
However my IDE (Eclipse) is showing an error "The constructor Customer(String,String) is undefined". Even though it's clearly there in the abstract class.
Note: just copying syntax from
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Also as an added question (which I could most likely sort out with experimenting):
The abstract Customer class implements some methods that are just simple accessors.My understanding is that unless these are instantiated in some way by retialCustomer, the object wont instantiate as all methods need implementations?
Thank you in advance for any hints or pointers you can give. Like I said, it seems simple to me, but at the same time, getting zilch :(
Your code looks fine. Rebuild it (you may also want to have a look at IntelliJ IDEA ;) ). Also please follow convention and rename your class to RetailCustomer.
The abstract Customer class implements some methods that are just simple accessors.My understanding is that unless these are instantiated in some way by retialCustomer, the object wont instantiate as all methods need implementations?
You probably need to rephrase this, because its unclear what your asking. All subclasses will inherit the parent class' implementation. Even if your parent class is abstract, if you implement some of the methods in your class, then all the child classes will inherit those implementations. Indeed, you will still not be able to instantiate your abstract class, but you are able to use those methods from your child classes.
If you're happy with what the methods do in Customer, there is no need to override them in RetailCustomer.
What I'm trying to do: as part of an assignment (so no big hints please, unless it's my IDE or something)
+1.

Storing different ojects in a container that have been extended from the same abstract class

Is it possible to store different objects that have been extended from the same abstract object in a single container and be able to access all of the custom fields of those objects. Let me present an example:
Suppose I have two cars: ford and honda. Since all cars have weight and color, I could make the following abstract class:
public abstract class Car{
private double weight;
private String color;
public Car(){
this.weight=0;
this.color="";
}
...getters and
...setters
}
Now suppose my Ford class has an additional field 'radio' and looks like this:
public Ford extends Car(){
private String radio;
public Ford(){
super();
this.radio = "generic";
}
}
Similarly, the Honda class has a custom field 'camera'
public Honda extends Car(){
private String camera;
public Honda(){
super();
this.camera= "analog";
}
}
Is it possible to keep the instances of these classes in a single container, something like the following below. Please note the code below works but this is not quite what I want. see comments below:
Ford ford = new Ford();
Honda honda = new Honda();
ArrayList<Car> myCars = new ArrayList<Car>();
myCars.add(ford);
myCars.add(honda);
HERE IS MY PROBLEM:
When I do myCars.get(0) I get an object of class Car (obviously) and am never able to get the custom field radio. Of course I could do something like ((Ford) myCars.get(0)) and will be able to see the radio field, but is it possible to create a better container what would reveal all of the fields without downcasting etc, something like:
myContainer.get(0) - would return the Ford class and I would have an access to weight, color and radio
myContainer.get(1) - would return the Honda class and I would have an access to weight, color and camera.
My hunch tells me that the solution is near and it is possible, but my expertise in Java is not up there yet. Maybe I have do to some sort of generics or hashmaps??
Thank you guys!!
There are several alternatives, none of which perfectly meets your ideal.
You could add all the getters for specific properties in your Car class and either return Null or throw an exception where they are not applicable.
You could apply the Visitor pattern.
You could create a CarContainer class that wraps your list and has methods that return all the elements of a specific type, e.g. List<Ford> getAllTheFords(). In this way you can hide the ugly casts in your container class.
I listed alternatives according to my personal preference :-)
What you could do is to use generics.
Your repository could implement these methods:
public static <T extends Car> T getFromRepository(Class<T> type, Object key)
public static <T extends Car> boolean addToRepository(Class<T> type, Object key, T value)
You could then call this with something like (presuming you already have the key for a Ford):
Ford ford = Repository.getFromRepository(Ford.class, fordKey)
Of course you can implement methods to get all the objects for a given type and so on...
PS: A simple alternative, if you can use the same method on the sub classes is the template method pattern:
http://en.wikipedia.org/wiki/Template_method_pattern
myCars.get(0) does return a Ford object. Except that this is only known at runtime. The problem is that to call car.radio, you need to know that it's a Ford and if it's not you can't call that method. So in any case you need to check the type and cast.
One solution would be to add a List<Accessory> field to your abstract class.
You can now write something like:
Car car = cars.get(0);
if (car.hasAccessories()) {
car.getAccessory(0).operate();
}
Not sure if that's what you need for your use case.

Class casting unclarity

I have the following abstract class:
public abstract class AbstractGroup {
private String name;
.
.
.
}
I have two empty classes that extend this abstract class:
public class GroupA extends AbstractGroup {
}
public class GroupB extends AbstractGroup {
}
Is there a way to cast the following without getting a ClassCastException:
(group is of type GroupA)
group = (GroupB)group;
I need this object instance to become GroupB.
It's not possible. You cannot cast classes horizontally but only vertically. GroupA is not the subtype of GroupB so the exception always will be raised.
No you cannot, because a GroupA is not an instance of GroupB.
How about:
public abstract class AbstractGroup {
public Enum Group { GroupA, GroupB; }
private String name;
private Group membership;
.
.
.
}
And then:
group.setMembership(GroupB);
No, you can't. You can cast up or down on Inheritance hierarchy.
What you are asking for is not called casting, but conversion. Both terms are covered by the umbrella term coercion. Java will not convert an object for you automatically and it couldn't even if it tried since this is generally an ill-defined problem. You must write your own code that will do the conversion -- either in the form of a conversion constructor, or some static conversion method, or maybe an instance method in the source object that returns the converted object.
No it isn't possible. But what you may like to do is add some constructor to the Groups to allow construction from a different implementation.
public class GroupA extends AbstractGroup {
public GroupA(AbstractGroup otherGroup) {
this.name = otherGroup.name;
}
}
However if you find yourself needing to do this then perhaps your design may be wrong.
Possible if you do something like:
GroupA groupAobj = new GroupA();
AbstractGroup abstractObj = (AbstractGroup) groupAobj;
GroupB groupBobj = (GroupB) abstractObj;
the code compiles and runs.

Categories

Resources