Я знаю, что в случае переопределения методов Java следует динамическому связыванию. Но если мы вызываем только дочерний метод из родительской ссылочной переменной, относящейся к дочернему объекту, мы получили ошибку компиляции.
Почему java следует этому дизайну (то есть почему нет динамического связывания во втором случае)?Почему различный дизайн для динамического привязки и вызова метода child only из родительского класса?
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();
}
Но во время выполнения следует динамическое связывание. Значения Я могу сказать, что для вызова 'a.sayHi()' compile попытайтесь найти 'sayHi()' объявление 'sayHi()' в A и, поскольку он существует там, поэтому нет ошибки. Затем во время выполнения вещи вызывается на основе объекта (т. Е. Адреса памяти), и там лежит определение C 'sayHi()', поэтому оно вызывается. И для метода 'sayGoodbye', когда вы получаете ошибку во время компиляции (как вы объяснили), не должно быть и речи о том, какое определение вызывается во время выполнения. –
@knoxxs. Да, точно. Во время выполнения не возникает вопросов о поведении, когда код даже не компилируется. –