Это относится к тому, что, когда не-переопределенный метод вызывается на объекте подкласса?

Рассмотрим следующий код:

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();
    }

}

У меня есть несколько вопросов.

  1. Когда объект подкласса создан, сколько объектов фактически создано? Только один, расширяющий свойства суперкласса путем введения новых свойств, определенных в подклассе? Или два: объект подкласса, к которому мы имеем доступ, и объект суперкласса, существование которого скрыто от нас?

  2. Если два объекта созданы, какой объект отвечает, когда не-переопределенный метод вызывается на объекте подкласса? Другими словами, что делает this ссылаетесь внутри не переопределенного метода? Скрытый объект суперкласса или объект подкласса?

  3. Если ваш ответ для #2 является скрытым объектом суперкласса, то почему код выше печатает "I am Employee" за System.out.println("I am " + getClass().getSimpleName()); внутри printClassName,

  4. Если ваш ответ для #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";
    }
}
  1. new Employee() создает один объект, содержащий два поля className. Он вызывает супер-конструктор, выполняет инициализацию поля и выполняет остальную часть кода конструктора.

  2. this всегда является единственным объектом, возможно, некоторого дочернего класса. Таким образом, Person.this на самом деле может быть Сотрудником.

  3. и 4. this.className in Person для объекта Employee просто получит доступ к полю Person, так как для полей нет наследования. В отличие от метода xxx() вызовет у ребенка самый метод.

Другие вопросы по тегам