Это относится к тому, что, когда не-переопределенный метод вызывается на объекте подкласса?
Рассмотрим следующий код:
class Person {
String className = "Person";
void printClassName () {
System.out.println("I am " + this.className);
System.out.println("I am " + this.getClass().getSimpleName());
}
}
class Employee extends Person {
// intentionally hiding this field
String className = "Employee";
}
public class App {
public static void main(String[] args) {
Employee raghu = new Employee ();
raghu.printClassName();
}
}
У меня есть несколько вопросов.
Когда объект подкласса создан, сколько объектов фактически создано? Только один, расширяющий свойства суперкласса путем введения новых свойств, определенных в подклассе? Или два: объект подкласса, к которому мы имеем доступ, и объект суперкласса, существование которого скрыто от нас?
Если два объекта созданы, какой объект отвечает, когда не-переопределенный метод вызывается на объекте подкласса? Другими словами, что делает
this
ссылаетесь внутри не переопределенного метода? Скрытый объект суперкласса или объект подкласса?Если ваш ответ для #2 является скрытым объектом суперкласса, то почему код выше печатает
"I am Employee"
заSystem.out.println("I am " + getClass().getSimpleName());
внутриprintClassName
,Если ваш ответ для #2 является объектом подкласса, то почему первая строка внутри
printClassName
печать"I am Person"
?
2 ответа
Вы объявляете переменную как тип Employee
this.className
относится к className
в этом классе.
this.getClass().getSimpleName()
this.getClass()
возвращает класс Employee
, так как вы объявили переменную, вот почему getSimpleName()
возвращает "Сотрудник"
Поле className в дочернем классе Employee - это дополнительное второе поле с тем же именем, что и поле className в Person; это называется слежка. Для полей нет наследования.
(Вероятно, известно.)
class Employee extends Person { // Manner to change the super field
Employee() {
className = "Employee";
}
}
new Employee()
создает один объект, содержащий два поля className. Он вызывает супер-конструктор, выполняет инициализацию поля и выполняет остальную часть кода конструктора.this
всегда является единственным объектом, возможно, некоторого дочернего класса. Таким образом, Person.this на самом деле может быть Сотрудником.и 4.
this.className
in Person для объекта Employee просто получит доступ к полю Person, так как для полей нет наследования. В отличие от методаxxx()
вызовет у ребенка самый метод.