Thursday, November 20, 2014

Inheritance – “A type of” relation NOT “contains” relation

Many times people confuse inheritance with “contains” relationship, which is not correct at all. Inheritance is “A type of” relationship not “contains” relationship. So a child is a superset of Parent’s abilities.

Example: Each fox is an Animal. But the other way is not always true (Not every Animal is Fox). Hence, Fox is a type of Animal.

class  Animal{

                                    1.   Ability of walking

}

class Fox extends Animal{

                         1.   Inherited abilities: Ability of Animal (walking)

                         2.    It’s own abilities (like hunting)

}

Now let's try to digest few concepts here.
When I write this :  Animal  a = new Fox(). What does it mean?
It means Fox is also an Animal or  every Fox is a type of Animal which makes sense too.

What about :   Fox  f = new Animal() 
It means Animal is a type of Fox or every Animal is a Fox, which is absolutely incorrect.

So "Fox is an Animal" is fine but the reverse doesn't make sense. For example, Apple is a Fruit, Car is a Vehicle etc. Remember inheritance is uni-directional. For example, House is a Building. But Building is not a House.

Let's formulate our finding in terms of coding: A reference to child class object can't refer to the parent class object. Whereas a reference to parent class object can refer to child class object.

Example 1: 
       Animal a =  new Fox();     //True
       Fox  f = new Animal();      //False (Compilation error)

Example 2:
       Animal a = new Animal();
       Fox f = new Fox();
       a = f;               //True
       f = a;               //False (Compilation error)

So we learned few things here: 
A child class object is inherently a parent class object. In simple terms, objects/reference of parent class can hold objects of child class but the reverse is not true.

Example 3:
public class TestMain {

       public static void main(String[] args) {

              Animal a = new Fox();

              a.walk();

              ((Fox)a).hunt(); //need to typecast because reference "a" doesn't hold "hunt" method

       }

}



class Animal{

       void walk(){

              System.out.println("Animal can walk");

       }

}



class Fox extends Animal{

       void hunt(){

              System.out.println("Fox can hunt");

       }
} 

Output:
Animal can walk
Fox can hunt


Few points to mention here:
1.  A subclass can't inherit private members of Superclass obviously.
2. Try to keep all variables private or protected and use public accessor(set/get) methods to access them.
3. On a light note: Initially don't try to learn this concept with "child" and "parent" example as you might get confused. Playing with a dog or a cat is safe and easier. :)