2016-09-16 3 views
0

Вот мой вопрос. У меня суперкласс с абстрактным методом.вызов абстрактного метода из объекта подкласса

public abstract class Base{ 

public abstract Boolean foo(); 

} 
public class sub extends Base{ 
@Override 
public Boolean foo(){ 
    System.out.printLn("This is foo in the sub class!"); 
} 
} 

так Когда я иду в основной и попробовать этот код

Base b = new sub(); 
b.foo(); 

Я не получил сообщение об ошибке и сообщение показывает на моем экране. Мое предположение заключается в том, что компилятор просматривает объект b и видит его как базовый объект, затем он переходит к foo из базового объекта и видит, что нет реализации после этого, он проверяет foo от дочернего элемента и затем видит метод foo реализован там, чтобы он показывал сообщение. Я прав?

+0

Пока вы скомпилируете базу, объект времени выполнения является вспомогательным. Метод вызывается на объект времени выполнения. –

+0

См. [Документация по абстрактным классам] (http://stackoverflow.com/documentation/java/87/inheritance/397/abstract-classes#t=20160916155332004042). – Jonathan

+1

Спасибо, ребята, поэтому метод объекта времени исполнения foo вызывается, а не метод базового класса foo, поэтому компилятор не жалуется на это. – MohsenFM

ответ

1

Компилятор не видит, если метод реализуется подклассу или нет. Он проверяет, присутствует ли метод, называемый ссылкой на конкретный тип класса, в самом классе или нет. Во время выполнения он решает, какой метод для вызова означает версию базового класса или версию подкласса.

Итак, вы правы до «Мое предположение заключается в том, что компилятор просматривает объект b и видит его как базовый объект, а затем он переходит к инструкции foo из базы».

1

Компилятор не выполняет столько обработки. Здесь в вашем случае Вы создали ссылочную переменную как ваш суперкласс, который будет удерживать объект дочернего класса.

Теперь, когда вы вызываете метод, он напрямую вызывает метод, присутствующий в вашем подклассе, на основе вашего типа объекта.

Я добавляю вам код с моими комментариями для справки.

1) Абстрактный класс, имеющий только объявление метода

public abstract class Base { public abstract Boolean foo(); //method declaration }

2) Детский класс продлив родительский класс, где вы должны реализовать метод, если вы объявляете этот класс как бетон класс.

public class sub extends Base { @Override public Boolean foo() { System.out.printLn("This is foo in the sub class!"); } }

3) Здесь вы объявили задающее ваш родительский типа, который хранящий объект из вас класса ребенка

Base b = new sub();

4), когда эта линия получится исполняемый компилятор будет проверять, что такое тип объекта и вызывать этот метод на основе типа объекта. Он не будет вызывать методы на t ype ссылочной переменной.

b.foo();