Firstly, you must understand what subclassing itself is.
If I have an object, let's say Tree, I may give that object a list of methods like plant(), water().
Then I want to define another class, AppleTree. Well an apple tree still needs to be planted and watered, so instead of copying that code from the Tree class, I'll just subclass it. So AppleTree extends Tree.
This means I can now call Tree's methods directly on an AppleTree object. Then maybe I'll add another method to AppleTree called harvest().
Now let's use this in another class. Maybe I have a class called Orchard that contains all my trees. Let's say I have 10 trees, and 2 of them are AppleTrees. In my orchard, I want to water all of my trees.
I can store all of my trees in an ArrayList like so:
ArrayList<Tree> trees = new ArrayList<Tree>();
for(int i = 0; i < 8; i++)
{
Tree t = new Tree();
trees.add(t);
}
for(int i = 0; i < 2; i++)
{
AppleTree a = new AppleTree();
trees.add(a);
}
I can then iterate through each of my trees in my ArrayList and call water() on each one.
for(int i = 0; i < trees.size(); i++)
{
trees.get(i).water();
}
However, now I want to harvest all of my trees, but only 2 of them are AppleTrees and know a harvest() method. So I can't do this:
for(int i = 0; i < trees.size(); i++)
{
trees.get(i).harvest(); //compiler error
}
This is because my ArrayList holds a set of Tree pointers, which don't know a harvest() method. Not all of my Trees are AppleTrees, and the class signature of Tree does not match the class signature of AppleTree.
All AppleTree objects are Tree objects, so this is ok:
Tree t = new AppleTree();
However, not all Trees are AppleTrees, so this doesn't work:
AppleTree a = new Tree(); //error
It's important to note though, that if I define a Tree this way:
Tree t = new AppleTree();
Even though t contains an AppleTree object, I can't call t.harvest() without casting t to an AppleTree, because to the compiler, it's just a Tree and doesn't know the harvest() method.
So this will fail:
Tree t = new AppleTree();
t.harvest(); //error
BisA. AllAare notB. This is why when you have aB, you can assign it to anAinstance. When you have anAinstance, you can't assign it to aBvariable. That's because not allAs areB.Bclass some new field or method. IfB b = new A();would be possible thenSystem.out.println(b.newField)should also be valid. Butbholds object of typeA, and that type doesn't havenewFieldso what should be result here? Probably some kind of exception, but this means we just broke Java's type-safety which is one of main reason people use that language. This problem doesn't exist withParent p = new Child()since we are sure that Child inherits from Parent everything which can be accessed viap.