File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Inheritance and Polymorphism Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Inheritance and Polymorphism" Watch "Inheritance and Polymorphism" New topic
Author

Inheritance and Polymorphism

Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Does any one know where I can get an excellent explanation about these important topics in a simply and intuitive way.
These topics are fundamental and yet sometimes confusing. One of the confusion I have is that if a member in the base class is private the derived class does not inherit it. If it does not inherit it how is it going to store values in the object it creates from the base class?
Michael Matola
whippersnapper
Ranch Hand

Joined: Mar 25, 2001
Posts: 1746
    
    2
Moving question to the Java in General (Beginner) forum because it's not specific to the Cattle Drive assignments.
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
When an object of the subclass is created on the heap, it will have a place in it for all of the fields that it has and all of the fields that it inherits from when the superclass constructor was executed. So the value of the superclass field is kept IN the subclass object. The subclass does not go back and store member variables in the superclass itself.
If the field is private in the superclass it will not be inherited by the subclass and there will not be a place for it in the object on the heap. So the subclass can not get at that variable, but it can get at the fields that it inherited.


"JavaRanch, where the deer and the Certified play" - David O'Meara
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
I am lost.
I do not understant this part of your answer. "If the field is private in the superclass it will not be inherited by the subclass and there will not be a place for it in the object on the heap. So the subclass can not get at that variable, but it can get at the fields that it inherited."
If for example the base class has a private member called studentName (a field). When an object of the derived class is created whehre is it going to store the studentName?
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
It isn't.
That is the point. As far as the subclass is concerned, that field does not exist.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Cindy, that isn't quite right. studentName has to be stored somewhere because the Base class might have a public getStudentName() method that allows the private property to be accessed. What Mulugeta doesn't realize is that when you create a child class you are also creating on the heap an object for every parent of the child class. So if we have a simple hierarchy of Base - Child we create three objects on the heap, Object, Base, and Child (all tied together) when we instantiate Child.


Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
I am not sure I understand your answer. When an object is created from the derived class where is the studentName stored if it is a private field in the super class? :roll:
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Hi Thomas,
Please expand on your answer a little. I am sure there is more to it for me to clearly understand the concept. By the way is there any material out there which clearly explains this.
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
Originally posted by Thomas Paul:
the Base class might have a public getStudentName() method that allows the private property to be accessed.


Well, yes, but then you are getting at it from the superclass, because the subclass can not. But your are correct, the superclass field IS out there - just marked private.
However I only ever considered it 1 object on the heap with 2 parts, one part for the superclass stuff and another part for the subclass stuff. What would the 3rd part have in it???
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Originally posted by Cindy Glass:
However I only ever considered it 1 object on the heap with 2 parts, one part for the superclass stuff and another part for the subclass stuff. What would the 3rd part have in it???
The parent of the superclass (and the parent of every class in Java), Object.
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
Duh!! :roll: the obvious - of course.
[ March 12, 2003: Message edited by: Cindy Glass ]
Derek Grey
Ranch Hand

Joined: Feb 09, 2002
Posts: 204
if a member in the base class is private the derived class does not inherit it. If it does not inherit it how is it going to store values in the object it creates from the base class?

The whole point of polymorphism and inheritance is to create a "Common Interface" for classes that are related. In such cases sometimes it so happens that a member field/method which belongs to the base class need not be accessed by the derived class. The interface is set in such a way that it's not required to access the member elements at all.
For instance take a base class called "Car"
and derived classes such as "Honda" & "Ford".
Now say if you had a member function called 'accelerateVehicle(int speed)'. Within this method we might have many fields and subfunctions such as 'gear', 'clutch', 'speedometer()' etc...these are something which are constructed by the base class programmer and are hidden (private/package access).
Now in order to accelerate your your "Honda" or "Ford" you still can do that by just calling car.accelerateVehicle(int speed). It's the same for both makes/models (atleast here ).
Derek Grey
Ranch Hand

Joined: Feb 09, 2002
Posts: 204
if a member in the base class is private the derived class does not inherit it. If it does not inherit it how is it going to store values in the object it creates from the base class?

The derived class inherits everything present in the base class. Always remember that the base class is a subset of the derived class.
Derived Class = Base Class + Something extra
Since you've written that "Something extra" you can access/modify it. But you can access only "public" declared fields/methods of the base class. The rest should be no concern of yours...its the headache of the programmer who wrote it (and has to maintain it.).
One of the biggest advantages that I've found while coding using these concepts is that debugging gets restricted to only the derived class (the one I create).
Alex McCormick
Ranch Hand

Joined: Mar 08, 2003
Posts: 31
Since you've written that "Something extra" you can access/modify it. But you can access only "public" declared fields/methods of the base class. The rest should be no concern of yours...its the headache of the programmer who wrote it (and has to maintain it.).

I think the part that confuses me (and possibly the original poster) is this:
In your example of having a "vehicle" base class, let's say there are 3 variables: size, weight, and speed. -all integer variables marked private. If I create a sub-class called "ford", it inherits basically everything from the vehicle class, so if I create a new ford object, it will have size, weight, and speed variables correct?
Assuming that's right, the part that I find confusing is that I can't directly access those variables - instead I have to use public methods that are in the vehicle class. (setSize, setWeight, etc etc) What's the logic behind this?
As an aside, isn't there a keyword "protected" that WILL allow you to access a base-class varible directly from a sub-class?
Thanks for any help!
Steve Fahlbusch
Bartender

Joined: Sep 18, 2000
Posts: 562
    
    7

What is with it is encapsulation.
You say there are three private attributes: size, weight and speed. Let's say someone has figured out how to calcuate weight from size. So the parent can change it's implementation, but as long as it supports and stays true to the public method, you don't need to change your class.
-steve
[ March 12, 2003: Message edited by: Steve Fahlbusch ]
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
I thank you all who gave a version of their answer to my question. However, I did not get a clear answer to by original question �if a member in the base class is private the derived class does not inherit it. If it does not inherit it how is it going to store values in the object it creates from the base class? �.
Since a private member in a superclass can not be inherited how is it possible for an object created from the subclass to store data in that field (the private member superclass field). And will these field live with the object created by the derived class? Some one suggested when we create an object from a derived class we also create two other objects � a superclass object and an instance of object class. This is confusing for me to say the least.
Your help is very much appreciated.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
A class is made up of itself and every parent of that class. That means when you instantiate a class you always get at least two classes (your class plus an Object class). You can not change things that are private in your parent. You can use your parent's public methods (which you inherit) to change them. The reason for this is simple. Only your parent knows the proper way to store variables in the parent object. If you were allowed to directly change your parents variables then you may chnage them in an invalid way without knowing it.

[ March 13, 2003: Message edited by: Thomas Paul ]
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Thank you Thomas. Your answer is clear and helpful. What happens when the parent is an abstract class? There wan't be an object of the abstract class and where is the private vaiables data that is in the prent class (abstract class) going to be stored?
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
The parent class is still created. The only thing that prevents an abstract class from being instantiated is that it has undefined methods. Since the child has provided those methods, the class can be instantiated.
Think of it this way, if abstract classes couldn't be instantiated then why are they allowed to have constructors? Abstract classes can be instantiated but not with new. They can only be instantiated through their non-abstract children. (Sort of like a dad who lives vicariously through his son. )
[ March 13, 2003: Message edited by: Thomas Paul ]
Donald R. Cossitt
buckaroo
Ranch Hand

Joined: Jan 31, 2003
Posts: 401
I had lunch with our software provider / maintenance people and of course we talked shop a great deal. A key person on the team is the one who advised me to come to JavaRanch. I am glad he did.
During the course of our discussions this individual made a statement that surprised me more than a little. I was sharing my difficulty in following code that extensively uses polymorphic behaviour. His comment to me was; "I have yet to use polymorphism in my coding experience." Admittedly, he is not the most senior person on staff nor has he many years of experience with JAVA, but that statement has left me wanting to ask the question: how important is polymorphism in the overall scheme of things?
doco
[ March 13, 2003: Message edited by: doco mastadon ]

doco
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Did that person ever use JDBC? Did he ever use an XML parser? Did he ever use an iterator? I would say that person doesn't know what polymorphism is if he doesn't think he has ever used it.
Steve Fahlbusch
Bartender

Joined: Sep 18, 2000
Posts: 562
    
    7

How about new!
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
If you've written an Applet or a Servlet, then the browser or container that ran your program took advantage of polymorphism to run it.


[How To Ask Good Questions] [JavaRanch FAQ Wiki] [JavaRanch Radio]
Donald R. Cossitt
buckaroo
Ranch Hand

Joined: Jan 31, 2003
Posts: 401
I am not sure that is what he meant. I believe what he meant was that he himself had not written any code that was polymorphic (Abstract, Interface, Implements, etc).
At any rae, I intend to learn it whether I use it or take advantage of it or not - but then why would one learn if one does not use; to know and not do is to not know.
Thanks
doco
[ March 14, 2003: Message edited by: doco mastadon ]
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
If a programmer is not making use of interfaces then they are not making use of design patterns. A Java programmer who is not using design patterns is not taking advatange of OO. It's like back in the old days when C++ first came around. A lot of the C programmers started writing procedural code in C++ and assumed they were doing OO.
[ March 14, 2003: Message edited by: Thomas Paul ]
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Thomas:
What about static and final mebers that are in abstract class - will the derived class inherit them too?
Thank you.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
static: no
final: yes, if it isn't also static


Java API Documentation
The Java Tutorial
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
From the JLS 12.5 Creation of New Class Instances

Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden (�8.3). If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (�4.5.5).
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
What about static and final mebers that are in abstract class - will the derived class inherit them too?
Yes and yes. The static class members are inherited by the subclass. Static class methods don't participate in the polymorphic behavior of the class instances.
John Flanery
Greenhorn

Joined: Mar 14, 2003
Posts: 5
Can't inheritance be thought of as a "fancy" form of include?
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Maybe a VERY fancy form of include.
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Any good reading material on Inheritance and Polymorphism?
Kathy Sierra
Cowgirl and Author
Ranch Hand

Joined: Oct 10, 2002
Posts: 1572
Howdy -- thought I'd add my bits...
One way to think about polymorphism is that anytime the reference variable type and the actual object type are different, polymorphism is happening! : )
So, to look at how polymorphism is used in the Java API (and in your own code), look at the reference variable type for the argument and/or return type of a method you're calling.
For example, if you put something in, say, an ArrayList (or any other collection), the ArrayList can't possibly have add() methods overloaded to take anything you could ever create to send it, so the ArrayList add() method looks like;
add(Object o)
Type 'Object' is the *ultimate* polymorphic type, because *any* type of object can be at the other end of an Object reference type...
Object obj = new Dog();
Object obj2 = new JButton();
etc.
So if Object is used as an argument type:
public void takeObject(Object o) {
}
ANYTHING can be passed to that method!
Dog d = new Dog();
takeObject(d);
JButton button = new JButton("click");
takeObject(button);
And so on...
So all of the collection classes (HashMap, LinkedList, ArrayList, etc.) all have methods that can take an Object, so that you can pass ANYTHING into those methods.
But the *real* object type is from whatever class *you* instantiated (Dog, JButton, etc.).
This lets you make incredibly flexible code. For example:
Imagine you're building the PetShop program. It's a simulation that will have dogs, cats, and birds. You're in charge of writing the PetShop program. So you write it like this;
class PetShop {
Dog[] dogArray;
Cat[] catArray;
Bird[] birdArray;
// methods that take a Dog, Cat, Bird and add them
// to the correct Array
void addDog(Dog d) {...}
void addCat(Cat c) { ... }
void addBird(Bird b) { ...}
// more methods here
}

class Dog {
void eat() {
// dog-specific eat behavior
}
void showHappiness() { }
}
class Cat {
void eatFood() {
// cat-specific eat behavior
}
}
class Bird {
void doEat() {
// bird-specific eat behavior
}
void beFriendly() { }
}
And imagine now it's time to call the eat() method on each of the animals in the PetShop. So you loop through each of the three arrays, and tell each Animal to eat.
for (int i = 0; i < dogArray.length; i++) {
dogArray[i].eat();
}

for (int i = 0; i < catArray.length; i++) {
catArray[i].eatFood();
}

for (int i = 0; i < birdArray.length; i++) {
birdArray[i].doEat();
}
And when it's time to be friendly or happy, you do the same thing, looping through each of the arrays and calling whatever the appropriate method is for that animal type (beFriendly(), showHappiness(), etc.)
Now you're done, and you leave to go on vacation.
But as soon as you leave, the spec changes (because as we all know, the spec ALWAYS changes )
NOW the spec calls for not just Dogs, Cats, and Birds, but also Turtles, Fish, and Rabbits.
You're stuck!
Your boss calls your cellphone and tells you to catch the next plane to get back and change it. You have to go back in and rewrite your entire PetShop class to add new methods and arrays, and you have to find out what the eat method signature is in each of those new animal classes.
But this time, you're smart (and desperate to get back to that tropical island). So you do the following to the PetShop program:
1) Rewrite all the Animal classes to extend Animal:
abstract class Animal {
public void eat();
public void beFriendly();
}
You make it abstract, because you want this class ONLY for the purpose of polymorphism, and you do not want anyone to instantiate an Animal, because what would it look like? What would it eat like? Too creepy to think about. There is no such concrete thing as an Animal. Only subtypes of Animal (Dog, Cat, etc.)
You give the Animal class an eat() method, so that ALL Animal subtypes (subclasses) will have the same eat() method, and so that eat() can be called polymorphically (you'll see in a minute).
Now you make all animal classes extend Animal, and you override the two methods, giving them behavior specific for that particular Animal type:
class Dog extends Animal {
public void eat() {...}
public void beFriendly() {...}
}
class Cat extends Animal {
public void eat() {...}
public void beFriendly() {...}
}
class Bird extends Animal {
public void eat() {...}
public void beFriendly() {...}
}
class Turtle extends Animal {
public void eat() {...}
public void beFriendly() {...}
}
and so on for each Animal type...
NOW your PetShop methods can be simplified!!
class PetShop {
Animal[] animals; // instead of one per type
public void add(Animal a) {
// instead of one add method for each kind,
// just have ONE method that can take ANY
// Animal subclass type
}
public void makeThemEat() {
// instead of looping through EACH array,
// loop through just the Animal array and call
// eat() on WHATEVER animal happens to
// be at that index in the array
for(int i = 0; i < animals.length; i++) {
animals[i].eat();
}
}
public void beHappy() {
// instead of looping through EACH array,
// loop through just the Animal array and call
// beFriendly() on WHATEVER animal happens to
// be at that index in the array
for(int i = 0; i < animals.length; i++) {
animals[i].beFriendly();
}
}

So now ALL your code is much simpler, and NOW you can go on vacation and when somebody else wants to come along and add new Animal types to the PetShop program, class PetShop doesn't have to change!! It can take ANY kind of Animal, as long as that new Animal extends class Animal. And that's what you tell your co-workers as you're heading out the door wearing your Hawaiin shirt: "If you want to add new animals to the PetShop program, just be sure that you make them subclasses of class Animal. That way, the class is guaranteed to have an eat() method and a beFriendly() method, and all methods in PetShop will be able to handle your new Animal type."
So everybody is happy.
Well, almost...
One day somebody comes along and wants to reuse your Animal class for a Zoo program. You think "no problem, OO is all about reuse." But then somebody points out that Tigers *do not*, *should not*, have a beFriendly() method. It appears that beFriendly should not be in class Animal, but should instead be in the lower-level subclasses. But if you do that, then you don't get to use polymorphism where you loop through an array of the superclass type, Animal, and call beFriendly() on each object.
What to do?
Make Pet an interface! That way, not all Animal types have to have a beFriendly() method.
class Animal {
void eat();
}
interface Pet {
void beFriendly();
}

class Dog extends Animal implements Pet {...}
class Cat extends Animal implements Pet { ...}
class Hippo extends Animal { }
// does NOT implement Pet!
And so on...
And here's the coolest part about interfaces -- you can have a class from some OTHER inheritance tree still be a Pet! So if someone comes along and adds virtual, computerized Pets which are clearly NOT actual animals, then they do not have to be from the same class hierarchy as the other animals, but can STILL be used in a PetShop program, if the PetShop takes Pet types instead of Animal types:
class RoboPet implements Pet {... }
// does NOT extend Animal
class PetShop {
// takes only things which are Pets
Pet[] pets;
void takePet (Pet p ) {...}
...
}

And:
class Zoo {
Animal [] animals; // may or may not be pets
void takeAnimal(Animal a) {...}
void doEat() {
// loop through and call eat()
}
}
So now you have reusable Animal classes, which do NOT assume that all Animal types can be pets and have a beFriendly() behavior. And you have a Pet interface so that if you want to use some Animal classes as Pets, you simply have those Animal subclasses also implement Pet. And if you want to have non-Animal types that can do Pet things, then have those non-Animal classes implement Pet, even though they do not extend Animal.
Flexibility, and the ability to take vacations without worrying about people reusing or extending your code, is one big key to polymorphism.
The more you design with polymorphism, the more flexible and powerful your code is.
The more you use interfaces and supertypes as arguments and return values (rather than more specific concrete subclass types), the more polymorphism you are using.
The other key to polymorphism is that in Java, ALL instance methods are virtual. In other words, if you invoke eat() on a Dog object, even though the reference type is Animal:
Animal a = new Dog();
a.eat();
It is ALWAYS the Dog's eat() method that runs.
The compiler cares deeply about the REFERENCE type. It checks the type of 'a', to see if it has an eat() method. Since eat() is defined in class Animal, no problem.
But at runtime, the VM cares deeply about OBJECT type. It looks on the heap to see what type of object is actually out there on the heap at the other end of the Animal reference. It finds a Dog, so it invokes the Dog's eat() method rather than the one in Animal.
Polymorphism is just a Beautiful Thing.
cheers,
-Kathy
p.s. sorry for such a long post, but I don't know how to talk about the Whole Big Thing without using examples, and I just get so excited about polymorphism that I go a little crazy
Mulugeta Maru
Ranch Hand

Joined: Jan 20, 2003
Posts: 68
Kathy:
Thank you very much. Polymorphism - what a thing of beauty. It is propably one of the most powerful feature of OOP.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Kathy, great explanation! Polymorphism is, indeed, a thing of beauty. And when an acolyte sees that he is well on the way to true OO wisdom!
Caitlin Gibson
Greenhorn

Joined: Nov 25, 2002
Posts: 12
Hi Kathy,
Thanks for the cool explanation. I did have a few questions though. In the code:
class RoboPet implements Pet {... }
// does NOT extend Animal
class PetShop {
// takes only things which are Pets
Pet[] pets;
void takePet (Pet p ) {...}
...
}
Isn't Pet an interface? If so, how can you create an array of Pet objects in the third line?
Also,
Animal a = new Dog();
a.eat();
Does new Dog return an instance of Animal since Animal is the object type? ( Animal is the superclass and Dog is the derived class? ).
I am a little confused when I see syntax like these:
Person kathy = new employee();
What *exactly is happening and how is that read?

Or...
Classname obj. = obj.methodcall();
Is Classname the Base class and yo are assigning the result of the method call to an instance of the
Classname?
Thanks.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Inheritance and Polymorphism