开发者

Questions about "casting operation" in OOP

When programming, we usually use some type-casting operations.

When the casting happens on the objects "on the same level", it feels ok. But when it happens on the ojects "on the different levels"(mainly between father and son), it feels weird.

Considering this:

Class Son extends Father

WhenSon s = (Son)father;, it's absolutely unreasonable. Because a "Son" is not a "Father" anymore, "Son" may grow up with some new properties "Father" doesn't have, the casting operation makes these properties unknown.

On the other hand, Father f = (Father)son seems reasonable, but according to LSP

"An instance of a derived开发者_JAVA百科 should be able to replace any instance of its superclass"

A "Son" can do anything his "Father" can, so the casting operation seems useless.

So can i say that these casting operations are agaisnt OO design principle but necessary?


Casting objects in OOP is usually the product of either class inheritance or interface inheritance. One has to always remember that class inheritance denotes an "is a" relationship, and interface inheritance denotes a "has a" relationship.

Let's go over to your example: Class Son extends Father doesn't sound like a reasonable abstraction, since every male person is a son, but not all of them will be a father. In fact, the opposite might be more applicable: Class Father extends Son because every father is always someone's son.

On the other hand, we could just ditch this whole abstraction and say that we have, instead, a Class Person that can either be a male or a female, a mother or a father, and so on. Each person will have an attribute containing collection of Person with name Children.

In this abstraction, a Person will only be considered a Father if its gender is male and if Person.Children.Count > 0. This is much simpler than defining a Father class in and by itself.


I find questions like these always interesting and it lends itself to some kind of debate I think :)

Here are my thoughts. In class design I would in this case create a class of Person

class Person
{
    public bool IsFather { get; set; } // this variable will change depending on the count of children
    public List<Person> children { get; set; }
}

When I create a derived class, the class should be a specialized person and in the case of Father and Son, I wouldn't create a Father class and a Son class.


You've got a bad example of inheritance.

A better one could be

Class Person 
{
    public void walk();
}
Class Man extends Person
{
    public void shaveBeard();
}

Inheritance is the way to represent an is a relationship; e.g. "a Man is a Person".

Using the Objects

Either of these lines is OK.

Person p = new Person();
Person m = new Man();

It is fine to call p.walk on both. However to call the shavebeard() method, m has to be a Man object. For reasons of type safety, you have to cast it to a Man object; e.g. (Man) m.shaveBeard(); The cast here will fail, so it's best to check that the variable refers to an instance of Man:

if(m instanceof Man)
{
   (Man) m.shaveBeard(); 
}


Neither seem reasonable to me. What seems more plausible:

Son s = (Son)person          //Valid
Father f = (Father)person    //Valid


Here's a hint: the Class on the left hand side is the superclass and that on the right side is the subclass so if we have this: Object p = new Student(); //is correct Student s = new Object() //is wrong...it's like saying that every Object is a student.. Care must be considered when doing explicit casting as it may look correct but might not work as expected. You can't instantiate your father's private property to yourself.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜