здесь работает код 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?
Вы не можете вызывать супер-метод в других объектах - это нарушит инкапсуляцию. Все дело в том, что объект контролирует то, что делают его переопределенные методы. Например, вы можете переопределить метод коллекции add
, чтобы генерировать исключение при определенных обстоятельствах, чтобы гарантировать, что в коллекцию будут добавлены только «действительные» элементы. Это было бы бессмысленно, если бы вызывающие абоненты могли просто обойти его с помощью преобразования!
Единственная причина, по которой объект может вызывать super.foo ()
для себя, - это возможность реализовать один вызов с использованием родительского элемента реализация. Это' s до кода в классе, чтобы убедиться, что он только когда-либо делает это разумно. Опять же, возьмем пример надстройки коллекции: если коллекция переопределяет добавить
, у нее должен быть какой-то способ добавления проверенного элемента в коллекцию, что выполните с super.add ()
.
Обратите внимание, что по той же причине инкапусляции вы можете только вызывать родительскую реализацию, а не реализацию прародителя, поэтому super .foo ()
является допустимым, а super.super.foo ()
- нет.
1:
Ваш вопрос не совсем Чисто. Что вы имеете в виду под «вызовом во время выполнения, как код»? Если вы спрашиваете, как экземпляр c знает, что это за суперкласс, тогда да, иерархия классов хранится в памяти и может быть доступна виртуальной машине.
2:
Java действительно позволяет вам преобразовать экземпляр своему родителю. Просто вызов метода в экземпляре всегда использует фактический класс экземпляра, а не его класс времени компиляции. Т.е. в Java все методы являются так называемыми виртуальными в C ++.