время выполнения / полиморфизм времени компиляции - PullRequest
2 голосов
/ 19 марта 2010

В приведенном ниже коде почему b1.subtract () не работает.Пожалуйста, объясните мне причину, т.е. что происходит в JVM при вызове этого метода.

class Base {

public void add() {
System.out.println("Base ADD");
}

}

class Child extends Base {

public void add(){
System.out.println("Child ADD");
}

public void subtract() {
System.out.println("Child Subtract");
}

}

class MainClass {

public static void main(String args[]) {

Base b1 = new Base();
Base b2 = new Child();

Child b3 = new Child();

b1.add();

b2.subtract(); // ?????????**previously it was b1.subtract and its wrong 

b2.add();
b3.subtract();

}

}

Ответы [ 9 ]

7 голосов
/ 19 марта 2010

Я предполагаю, судя по названию, что код на самом деле должен был быть b2.subtract(). Идем с этим:

Хотя b2 в настоящее время является экземпляром Child, и довольно легко увидеть, что в вашем коде это всегда будет экземпляр Child, Java статически типизирована и поэтому не может позволить вам использовать методы фактического класс, просто объявленный класс.

Рассмотрим этот пример:

Base b2 = Math.random() > 0.5 ? new Base() : new Child();
b2.subtract();

Теперь невозможно сказать во время компиляции, какой экземпляр b2 на самом деле будет экземпляром, поэтому вы, очевидно, не можете вызывать какие-либо методы в Child (поскольку b2 может быть просто Base!). Не было бы никакого смысла в том, чтобы быть исключением из этого для случаев, подобных вашему примеру, так как это могло бы вызвать lot путаницы, и эти случаи можно легко исправить, чтобы они работали как есть изменение объявленного типа на дочерний, а не базовый).

1 голос
/ 19 марта 2010

Класс не компилируется!Предполагая, что вы хотите проверить, работает ли объект базового класса, инстанцированный с дочерним классом, или нет, ответ - да.

    Base b1 = new Base();
    Base b2 = new Child();

    Child b3 = new Child();

    b1.add();

    ((Child) b2).subtract(); // ?????????**

    b2.add();
    b3.subtract();

Это будет работать, и результат, который он дает, будет таким, как показано ниже.1005 *

Это то, что называется полиморфизмом времени выполнения.

1 голос
/ 19 марта 2010

В JVM ничего не происходит, потому что код не будет компилироваться. Метод b1.subtract() не может быть разрешен компилятором, поскольку у Base нет такого члена.

0 голосов
/ 06 января 2015

Java - строго статически типизированный язык. Родительский класс не может указывать на методы дочернего класса. Во время компиляции Java-компилятор использует принцип замыкания и видит, есть ли в базовом классе метод вычитания, поскольку в этом случае нет метода вычитания, это приводит к ошибке времени компиляции.

0 голосов
/ 19 марта 2010

метод subtract () не является частью интерфейса базового класса, поэтому он не работает.

0 голосов
/ 19 марта 2010

Компиляция не удалась, потому что у класса BASE нет метода вычитания. И b1 имеет тип base.

0 голосов
/ 19 марта 2010

Вызов b1.subtract() может быть разбит на используемые классы.

b1 -> Base

subtract() -> Child

Поскольку b1 является Base, а не Child, вызов b1.subtract() никогда не будет работать, поскольку b1 не имеет метода с именем subtract().

0 голосов
/ 19 марта 2010

потому что у Базы нет вычитания.

b2 и b3 имеют вычитание, потому что они определены как дочерние.

[Edit:] Нет, подождите, у b2 нет вычитания, даже если оно определено с помощью нового метода Child (), оно все равно объявлено как Base.

0 голосов
/ 19 марта 2010

Переменная b1 имеет тип Base. Этот класс не имеет subtract() метода, поэтому он не может скомпилироваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...