Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I read this code somewhere

class Foo {
    public int a;
    public Foo() {
        a = 3;
    }
    public void addFive() {
        a += 5;
    }
    public int getA() {
        System.out.println("we are here in base class!");
        return  a;
    }
}

public class Polymorphism extends Foo{
   public int a;
   public Poylmorphism() {
       a = 5;
   }
   public void addFive() {
       System.out.println("we are here !" + a);
       a += 5;
   }

   public int getA() {
        System.out.println("we are here in sub class!");
        return  a;
    }

    public static void main(String [] main) {
        Foo f = new Polymorphism();
        f.addFive();
        System.out.println(f.getA()); // SOP 1
        System.out.println(f.a);      // SOP 2
    }
}

For SOP1 we get answer 10 and for SOP2 we get answer 3. Reason for this is that you can't override variables whereas you can do so for methods. This happens because type of the reference variable is checked when a variable is accessed and type of the object is checked when a method is accessed. But I am wondering, just why is it that way? Can anyone explain me what is the reason for this behaviour

share|improve this question
2  
Because the Java Language Specification says so? –  user1249 Sep 16 '12 at 12:40
    
c'mon you are almost at 35K, you must be knowing the real cause ;) –  Shades88 Sep 17 '12 at 10:26
2  
No, I don't. I did not design Java. The JLS is the Word of God in that regard. –  user1249 Sep 17 '12 at 11:06
add comment

2 Answers

up vote 4 down vote accepted

Your reference is of type Foo; it does not know the type of the object it's referring to.

Even with this, inheritance breaks encapsulation; by permitting the instance fields to be overridden too, encapsulation would be broken even more. Maybe in your subclass you are calling a method from the superclass which relates on the state of the instance field a. The superclass' implementation is based on it's own a (it cannot assume a superclass will exist and it will override it) and will have a very chaotic behavior if you change it by overriding it.

Also, instance field inheritance should not be permitted since instance fields should be made private.

share|improve this answer
add comment

This happens because type of the reference variable is checked when a variable is accessed and type of the object is checked when a method is accessed. But I am wondering, just why is it that way? Can anyone explain me what is the reason for this behaviour

It is not a type issue, it is a binding issue.

  • The f.a expression binds statically to the field according to the declared type of the variable f because fields are cannot be overridden. And the reason that they cannot be overridden is that that could break substitutability (for non-private fields) and break methods declared in the supertype that use the field.

  • The f.getA() call binds dynamically to the method in the actual object in order to implement dynamic polymorphism, and in order to prevent callers from breaking abstraction by mistakenly calling a method that had been overridden.

In short, if the binding method was different in either case, the net result would be a less expressive language with problems maintaining abstraction boundaries.

Most, if not all, statically typed OO languages work this way. (If anyone knows of counter examples that are also statically typed, please comment.)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.