Software Engineering Asked on October 29, 2021
I want to make diagrams that explain how Inheritance and Polymorphism work conceptually.
Assume that we have a Cat
class that inherits from the Animal
class. The way that I can think of a Cat
object is that it is an object that contains a copy of the members of the Cat
class and also it have an Animal
object inside of it.
Note: technically, I think that all Cat
objects share the same copy of the methods of the Cat
class, however, it is clearer to conceptually think of every Cat
object as if it contains its own copy of the methods of the Cat
class.
Now when we do:
Cat cat1 = new Cat();
Then cat1
will point to the Cat
object, this is how the diagram would look like:
The operations that are allowed on the cat1
variable are the following:
cat1.x
(will access the x
variable inside the Cat
object).
cat1.move()
(will call the move()
method inside the Cat
object).
cat1.jump()
(will call the jump()
method inside the Animal
object).
And when we do:
Animal animal1 = cat1;
Then animal1
will point to the Animal
object that is inside the Cat
object, this is how the diagram would look like:
Note: the arrow pointing at the Animal
object doesn’t mean that animal1
actually point to a different location in memory than cat1
, the truth is that animal1
and cat1
point to the same location in memory, the arrow pointing at the Animal
object is just to indicate that animal1
can only access the members inside the Animal
object (unless we have an overridden method).
The operations that are allowed on the animal1
variable are the following:
animal1.x
(will access the x
variable inside the Animal
object).
animal1.move()
(now if the move()
method is not overridden in the Cat
class, then animal1.move()
should call the move()
method inside the Animal
object, however, since the move()
method is overridden in the Cat
class, then animal1.move()
would call the move()
method inside the Cat
object).
animal1.jump()
(will call the jump()
method inside the Animal
object).
Is my understanding correct?
I think to do this right you need to detach the method names from the object blocks. The whole point of polymorphism is the separation of the interface from the implementation. It does not help to see the method names within a particular object block, that is only confusing. The method names should be on the outside, at the outer edge of the outer block. Then some lines can route them to the inners of a particular object where the attached implementation is, without repeating the member names. The point is to show where the pipes end up.
Another thing that is (utterly) wrong in the drawings shown is that when you cast the object to Animal, the arrow goes to Animal. This is not the case, the arrow should still go to Cat! You will be talking to a Cat no matter what you cast it to. Once you understand this you really understand polymorphism and it will get a lot easier, this is what you want to make clear.
[edit]
The pictures are portraying the objects (ancestor and descendant) as separate things which gives the wrong idea. The point is they are the same, which is not conveyed by the image. Descendant does not encapsulate/contain ancestor, descendant is an extension/modification of ancestor. Once the cat object is instantiated there is no animal object.
The animal class is used as a blueprint to construct part of the cat object but the result will be a cat. Think of the real cat, does it have an animal inside of it? No. So the "animal object" box within the cat object box is inappropriate, it is all cat.
Answered by Martin Maat on October 29, 2021
In the second case, with polymorphism, animal1.move()
will still invoke move()
of the Cat
. In this regard, the diagram is misleading.
If you want to get this right and unambiguous in a diagram, you'd have to draw some kind of redirection of the call to the right method whatever the type that is used:
Elaborating on what you did, I could fo example imagine something like this:
The second alternative that I mentioned, uses the lollipop connectors that you typically find in an UML component and the view of the internal subobjects like you'd fin in an UML composite structure:
I hesitated to show it, because it looks like UML, but it's not valid UML. The lollipops for example are used to show public members instead of full interfaces, and the ports are misused to route the call to the right implementation instead of component elements. In addition your typed object handles do not consume the interface but provide. On the other side, it could have advantages to familiarize your students intuitively with these modelling principles: it's a good opportunity to make seem natural what otherwise looks rather abstract.
Answered by Christophe on October 29, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP