• Post Reply Bookmark Topic Watch Topic
  • New Topic

Inheritance  RSS feed

 
Kenneth Van Gysegem
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have a question about a part of inheritance i dont fully understand.

If a class Mammal extends a class Animal.
And a class Cat extends the Mammal-class.

Then what is the difference between:


Has cat1 all the properties and methods of the extended classes and the ones specific to the Cat class?
While cat2 only has the properties and methods of the Animal class, but is able to be downcasted to the Cat class?
And finally if the previous is correct then what is the difference between:


Because as I understand it cat3, can be downcasted to the Cat class too, if it is tested to be an instance of the Mammal- and Cat-class.
Or am I understanding this totally wrong?

Thanks in advance,
Kenneth

 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

You have to distinguish between the variable and the object it references.

In this case, cat2 is a variable of type Animal. So you can only directly access properties and methods of the Animal class via cat2. However, the object it's referencing is really a Cat, and it does have all those properties and methods. To get at them you need a Cat variable, which is where the casting comes in:


In the following case:

Now you've got an Animal variable referencing an Animal object. You can use cat3 in the same way as you can use cat2. But now try casting it to a Cat reference. The compiler will allows it - as far as the compiler is concerned it's the same case as before. Casting tells the compiler "I know you think this is really an Animal, but trust me, it's a Cat". The compiler doesn't know what the runtime type will be, so it will take your word for it. But now you'll get an error at runtime (a ClassCastException), because the JRE does check that all cast are valid at the time they actually happen.

One important thing to remember: casting changes the type of the variable, but it does not change the type of the actual object referenced.

Does that help?
 
Wayan Saryada
Ranch Hand
Posts: 119
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following article can help you: How my Dog learned Polymorphism
 
Campbell Ritchie
Marshal
Posts: 56597
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are any of those classes abstract? If the Animal class is abstract, then you cannot instantiate Animal as such.
If you declare a reference as type Animal, then the compiler will expect to see the methods of the Animal class, eg eat(). If the Cat class has an additional method called eatMice(), that will be “invisible”. (It would also be dubious design to add such methods in subclasses.)
You would find your question easier to understand if your variable names reflected their declared type.
Animal cat3 = new Animal(); is potentially misleading. There is no evidence that cat3 actually points to a Cat object; in fact if you try to cast it to a Cat, that will definitely fail. If you are lucky it will produce a compile‑time error and if you are unlucky an Exception at runtime.
If you had written Animal an3 = new Animal(); the type of the reference would have been obvious. If you later write an3 = new Cat(); then you have it pointing to a Cat object and all methods of the Cat class are there, but you may need a cast to make them visible to the compiler.

Of course narrowing reference type casting (what you call downcasts) is dubious programming, as is adding functionality to subclasses.
 
Kenneth Van Gysegem
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all for the quick reactions!

I think I understand a bit better.
so if i would state


I'm actually telling the compiler that an1 is an object of Animal, and it uses all it's methods and properties.
But if I would downcast it to the Cat-class, the compiler would use the overridden methods in the cat class and use its extra properties?
But it's better to state:
Cat an1 = new Cat(); if I am going to use the methods and properties in the Cat class.

or does state that an1 is an object of the cat class, the compiler however thinks its an animal, but if I use a method on the object that is overridden in the Cat class it will use the overridden method?

I think i'm still mixing things up.
up and downcasting I understand, I know how an object gets instantiated, and I know how inheritance works, but this i find pretty tricky.

regards,
Kenneth

 
Campbell Ritchie
Marshal
Posts: 56597
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kenneth Van Gysegem wrote:Thanks all for the quick reactions!

I think I understand a bit better.
so if i would state


I'm actually telling the compiler that an1 is an object of Animal, . . .
No, you are telling yourself that an1 is a reference to an Animal. You could write Animal xyz = … and the compiler will be happy with it. You do not have to write code for the compiler to understand, but for you yourself to understand.
The compiler will use all the methods in Animal, and the runtime environment will look for the methods overridden in Cat. You do not need any casts in that assignment at all; they have no effect. Except possibly Animal an1 = (Dog)new Cat();

You only need to write Cat cat1 = new Cat(); to use methods which occur in the Cat class and not in the Animal class. If the methods occur in the Animal class, then you can still write Animal an1 = new Cat(); And you always get the most specific overridden versions of any methods. That is what polymorphism (as I Wayan Saryada gave a link about) means.
What you can do if you declare a reference as Animal is this:-Obviously calling a Cat a Dog (as in the small writing above) will not work.

What you are doing in all those assignments to an1 is calling a Cat an Animal. Imagine it goes from right to left. In my last bit of code, you are calling a Cat an Animal in line 1, calling a Dog an Animal in line 3 and calling a Horse an Animal in line 5. You often cannot call an Animal a Cat, so Cat cat1 = (Cat)an1; may cause an exception at runtime. And you can never call a Cat a Dog, as in the small writing. So this sort of code may fail with an Exception:-
 
Kenneth Van Gysegem
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Allright!!

I do understand now. Thank you very much for the explanation.
I did read the article provided by I Wayan Saryada, but your answer made things much more clear.

thanks again,
Kenneth
 
Campbell Ritchie
Marshal
Posts: 56597
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You’re welcome
I often find that person A understand explanation A and person B understand explanation B, so it is worth having several different explanations.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!