문제

I know for the case of overriding methods Java follows dynamic binding. But if we call a child only method from the parent reference variable, which is referring to child object, we got compilation error.
Why java follow this design (i.e. why no dynamic binding in second case)?

class A{
    public void sayHi(){ "Hi from A"; }
}


class B extends A{
    public void sayHi(){ "Hi from B"; 
    public void sayGoodBye(){ "Bye from B"; }
}


main(){
  A a = new B();

  //Works because the sayHi() method is declared in A and overridden in B. In this case
  //the B version will execute, but it can be called even if the variable is declared to
  //be type 'A' because sayHi() is part of type A's API and all subTypes will have
  //that method
  a.sayHi(); 

  //Compile error because 'a' is declared to be of type 'A' which doesn't have the
  //sayGoodBye method as part of its API
  a.sayGoodBye(); 

  // Works as long as the object pointed to by the a variable is an instanceof B. This is
  // because the cast explicitly tells the compiler it is a 'B' instance
  ((B)a).sayGoodBye();

}
도움이 되었습니까?

해결책

Before the dynamic dispatch of method invocation could come into action, the code has to go through the compiler. When you invoke a method using a reference of a class C, compiler looks out for declaration of that method in that class C. Compiler only worries about what the reference type it is. It can only validate a method invocation on that much information. If it can't find the method in class C it will give you compiler error.

So, for the invocation:

a.sayGoodBye(); 

Since a is an reference of class A, compiler will look for the method in class A, and if it cannot find, it will give compiler error.

다른 팁

B is a A, but A is not necessarily B. So B's method cannot be invoked on A reference

Think it like that: When B extends A; it means

B = <All non-private stuff of A> + Its own stuff

It means B has all the privilege to use the stuff of A. (Its like A becomes a subset of B)

But A never knew about B here and what B contains; so, it cannot use B's stuff. If someway it is need to force A to behave like B (we use cast) and since here A is not B; the casting will fail at runtime.

To know more about Java casting, please read This thread

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top