views:

61

answers:

3

If a Father is a Parent and a Parent is a Person and a Person has a Father I create the following:

 class Person{
  Father father;
 }
 class Parent extends Person{}
 class Father extends Parent{}

Instances:

Person p1 = new Person();
Person p2 = new Person();
p1.father = p2; //father is of the type Father

This doesn't work... Now try casting::

Person p1 = new Person();
Person p2 = new Person();
p1.father = (Father)p2;

This doesn't work either.

What does work for this case?

+1  A: 

Actually, Father is not a sub class of person. It is just a relation.

 class Person {
    Person father;
 }
Maxem
Unless that specific Person had to do something like doParent(Person other).. An interface might be nicer though!
filip-fku
Every Person has a father, every person can have one or more children, so every person would have that method.
Maxem
@Maxem - Firstly I agree if that fits the needs. But sometimes that generalization might not be enough. For argument's sake, what if we also need to keep track of the mother? A mother can breastfeed, a father can't. Decorator pattern perhaps? I am just trying to learn myself, not argue!
filip-fku
That really depends on what you want to do. In this case I'd probably go with either a behaviour wrapper or the decorator pattern.The person has a property Mother, the setter should then check that the value is indeed a female person. You can now be sure, that you are dealing with a female person when ever you use this mother property and with that assumption you could use something like IMotherBehaviour or how ever else you'd like to do this.
Maxem
I want to assign properties to a Father and a Parent. In that case these are not relations, but Object on their own.
hsmit
A: 

You cannot cast like that. Your person is not a father so casting to one won’t work. You can only cast to something that the object is.

Person p1 = new Person();
Person p2 = new Father();
p1.father = (Father)p2;

Or directly:

Father p2 = new Father();
p1.father = p2;

But being a father isn’t a good differentiation in the class hierarchy. I probably wouldn’t create an own class for it: being a father is just one of many roles that one person fulfils so I would remove that class and declare the father member as a regular Person. Same for Parent.

Konrad Rudolph
I want to assign properties to a Father and a Parent. In that case these are not relations, but Object on their own.
hsmit
@hsmit: That’s simply a bad design. Your decomposition of the problem is at fault. If you want to add extra properties, use composition instead of inheritance. Inheritance is simply not suited to model your requirements.
Konrad Rudolph
@Konrad: What do you propose
hsmit
@hsmit: As I said, I propose [composition](http://en.wikipedia.org/wiki/Object_composition). For example, each `Person` could have a `List<Role>`, i.e. a list of roles which they perform, where `Role` is simply some interface. Now you could implement each role, e.g. `ParentRole`, `FatherRole` etc.
Konrad Rudolph
+1  A: 

The most obvious thing is that a Father IS a Person. A Person does NOT have to be a Father though, when it comes to the concrete instance. This example specifically, would work if you father field was of type Person, or you instantiated p2 as a new Father.

filip-fku
I agree. I choose for the last one: p1.father = new Father(p2); But how should I push all p2's values into the super class Person?
hsmit
Just call Person's constructor from Father's constructor - super(1,2,3)
filip-fku