HakunaMatata
HakunaMatata

Reputation: 834

Inheritance in java : object state and behavior

Java is object oriented programming language.Inheritance is one of most important features. We use encapsulation to hide object states.In the below program i should have used private access modifier for age and counter but to test this inheritance i have used public.

  1. Why inheritance does not work in case of direct object state access (primitive types or object reference). SOP 3 output is different from expected.
  2. Since compiler does not give any error in line SOP 13 and SOP 14. Why Father class details are printed not child class.

.

public class Father {

    public int age = 50;
    /*
     * Counter keeps track of total no of instances created so far.
     */
    public static int counter = 0;

    public Father(){
        super();
        synchronized (Father.class) {
            ++Father.counter;   
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Father.counter;
    }

}

public class Child extends Father {

    public int age = 25;
    public static int counter = 0;

    public Child(){
        super();
        synchronized (Child.class) {
            ++Child.counter;    
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Child.counter;
    }

    public static void main(String args[]){

        Father father = new Father();
        Father child = new Child();
        Child realChild = new Child();

        System.out.println("Expecting Father Class details to be printed");
        System.out.println("SOP 1 : Father Age : "+father.age);     //prints 50 as expected.
        System.out.println("SOP 2 : Father Age : "+father.getAge());//prints 50 as expected.

        System.out.println("Expecting Child Class details to be printed");
        /*
         * Why inheritance does not work in case of direct integer access.
         */
        System.out.println("SOP 3 : Child Age : "+child.age); //prints 50 ?? , Father Age . Why ?
        System.out.println("SOP 4 : Child Age : "+child.getAge());//prints 25 as expected.

        System.out.println("Expecting Child Class details to be printed");
        System.out.println("SOP 5 : Child Age : "+realChild.age); //prints 25 as expected.
        System.out.println("SOP 6 : Child Age : "+realChild.getAge());//prints 25 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name. 
         */
        System.out.println("SOP 7 : Father Instance Count : Using Class Reference :"+Father.counter);
        System.out.println("SOP 8 : Father Instance Count : Using Class Reference :"+Father.getStaticCount());

        /*
         * Incorrect Way to use static. Since Compiler allows this lets see output.
         */

        System.out.println("SOP 9 : Father Instance Count : Using Object Reference :"+father.counter); //prints 3 as expected.
        System.out.println("SOP 10 : Father Instance Count : Using Object Reference :"+father.getStaticCount());//prints 3 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name.  
         */
        System.out.println("SOP 11 : Child Instance Count : Using Class Reference :"+Child.counter); // output is 2 as expected
        System.out.println("SOP 12 : Child Instance Count : Using Class Reference :"+Child.getStaticCount()); // output is 2 as expected

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ? Inheritance does not work for static fields.
         */
        System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
        System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ?
         */
        System.out.println("SOP 15 : child Instance Count : Using Object Reference :"+realChild.counter); // output is 2 as expected
        System.out.println("SOP 16 : child Instance Count : Using Object Reference :"+realChild.getStaticCount()); // output is 2 as expected
    }

}

My question is why inheritance only works for instance methods. Why output is different for SOP 3, SOP 13 and SOP 14.

Upvotes: 1

Views: 1521

Answers (4)

Cratylus
Cratylus

Reputation: 54094

The reason is that polymorphism does not apply to instance variables. What you are doing is variable shadowing.

In SOP 3 and 4 the variable with the same name in the child class shadows the variable in the base class. And since this is resolved at compile time the value of the static type is chosen.

In SOP 13 and SOP 14 this happens for the same reason. At the scope of the method the child's class hiding variable is unknown.

From JSL:

The scope of a declaration of a member m declared in or inherited by a class type C (§8.1.6) is the entire body of C, including any nested type declarations.

Upvotes: 3

Tushar Paliwal
Tushar Paliwal

Reputation: 301

System.out.println("SOP 3 : Child Age : "+child.age);
System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

In above example you created object of child class Father child = new Child(); and store this in father class reference variable which is super class of child. if you will try to call any methode or try to access any instance variable by "child" reference variable it firstly checked in super class and then then to sub class if it is found in super super is get executed.

Upvotes: 0

Stephen Connolly
Stephen Connolly

Reputation: 14116

When the compiler is looking at the line for SOP 3 it is not to know that child contains anything other than a Father instance... the fact that you have put a sub-class into it is irrelevant, the compiler will bind the field lookup based on this being a Father class... so it accesses the Father.age integer field so the expected output is 50 not 25.

SOP 13 is the same as for SOP 3... the only difference is that you are accessing a static field via an instance variable... this is considered bad style because it can cause just the confusion you have had.

SOP 14 is accessing a static method via an instance... and again the variable is holding objects of class Father, so it is Father.getStaticCount() that is returned. Again this is bad style.

You could get similar effects by accessing ((Father)realChild).age, Father.counter and Father.getStaticCount as in each case you are specifying that you want the field/method of the Father class.

This is a result of there not being field overloading in Java and that static methods are not overloaded either.

If you want to access the parent field from within the child class, you just need to invoke the cast to the parent class.

Upvotes: 0

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33544

("SOP 3 : Child Age : "+child.age);

There's no such thing as "overriding fields". You can shadow fields, but you can't override them. Fields aren't polymorphic. See section 6.4.1 of the Java Language Specification for more details.

/////--------------End of Question:1-------------------/////

("SO 13 : child Instance Count : Using Object Reference :"+child.counter);

child.counter is pointing to the static counter variable in Father class, as i mentioned before that Fields are not Polymorphic

/////--------------End of Question:2-------------------/////

("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount());

child.getStaticCount() is pointing to the static counter variable of class Father,

Try it out with realChild, the result will be 2, as expected, as its pointing to the static counter variable of Child Class

System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+realChild.getStaticCount());

Upvotes: 1

Related Questions