Java может назвать родительский переопределенный метод в других объектах, но не подтипе?

здесь работает код Java

class Cup {
    public String sayColor() {
        return "i have a color .";
    }
}

class TCup extends Cup{
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"color is tee green.";
    }
}

class MyTCup extends TCup {
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"but brushed to red now!";
    }
}
class Test {
    public static void main(String[] args) {
        Cup c = new MyTCup();
        System.out.print(c.sayColor());
    }
}

и выполнение Тестовой печати класса

MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!

вопрос 1: Во времени выполнения типом объекта C является MyTCup, но это может всегда называть вышестоящий метод. Существует ли стопка метода в памяти в MyTCup после инициализации объекта и затем может звонить через во времени выполнения как код?

вопрос 2: нет никакого способа назвать вышестоящий метод в других объектах. Как я знаю, C++ может бросить для вызова родительского метода в любое время. Почему это отличается в Java?

36
задан Dov Vachman 2 July 2019 в 17:24
поделиться

2 ответа

Вы не можете вызывать супер-метод в других объектах - это нарушит инкапсуляцию. Все дело в том, что объект контролирует то, что делают его переопределенные методы. Например, вы можете переопределить метод коллекции add , чтобы генерировать исключение при определенных обстоятельствах, чтобы гарантировать, что в коллекцию будут добавлены только «действительные» элементы. Это было бы бессмысленно, если бы вызывающие абоненты могли просто обойти его с помощью преобразования!

Единственная причина, по которой объект может вызывать super.foo () для себя, - это возможность реализовать один вызов с использованием родительского элемента реализация. Это' s до кода в классе, чтобы убедиться, что он только когда-либо делает это разумно. Опять же, возьмем пример надстройки коллекции: если коллекция переопределяет добавить , у нее должен быть какой-то способ добавления проверенного элемента в коллекцию, что выполните с super.add () .

Обратите внимание, что по той же причине инкапусляции вы можете только вызывать родительскую реализацию, а не реализацию прародителя, поэтому super .foo () является допустимым, а super.super.foo () - нет.

69
ответ дан 27 November 2019 в 05:47
поделиться

1:

Ваш вопрос не совсем Чисто. Что вы имеете в виду под «вызовом во время выполнения, как код»? Если вы спрашиваете, как экземпляр c знает, что это за суперкласс, тогда да, иерархия классов хранится в памяти и может быть доступна виртуальной машине.

2:

Java действительно позволяет вам преобразовать экземпляр своему родителю. Просто вызов метода в экземпляре всегда использует фактический класс экземпляра, а не его класс времени компиляции. Т.е. в Java все методы являются так называемыми виртуальными в C ++.

1
ответ дан 27 November 2019 в 05:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: