У меня два класса

public class Person {
    public String name = "person";
    public String getName(){
      return name;
    };
}

public class Teacher extends Person{
    public String name ="teacher";

    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        System.out.println(teacher.name);
    }
}

  1. вывод "человек", почему?

** неважно, изменение свойства имени является частным или общедоступным, результатом всегда является «человек», но то, что я узнал до сих пор, сказало мне, что если подкласс наследуется от суперкласса, он также содержит методы из суперкласса, поэтому, когда я вызываю метод объекта подкласса, имя в методе должно быть this.name, и это должен быть учитель, верно?, но почему я все еще получаю имя суперкласса? **

0
zfing 27 Ноя 2022 в 06:09
Это мое первое время, чтобы задать вопрос, если я делаю что-то не так или глупо, пожалуйста, простите меня, ребята
 – 
zfing
27 Ноя 2022 в 06:11
Вы не опубликовали реальный исполняемый код. Пожалуйста, сделайте это, потому что это позволяет вам задать вопрос о реальной ситуации с Java. Трудно понять, о чем вы спрашиваете, когда код, который вы публикуете, не является компилируемым Java.
 – 
tgdavies
27 Ноя 2022 в 06:18
Спасибо за предложение, я изменил вопрос
 – 
zfing
27 Ноя 2022 в 06:39

2 ответа

В основном это вопрос охвата. Переменные private доступны только для определяющего класса. В вашем случае за реализацию геттер-функции отвечает базовый класс, и он будет знать только о своих переменных.

Базовый класс не может знать о переменных, определенных в подклассах (это, возможно, чрезмерное упрощение, как и некоторые пояснительные детали в предложениях ниже, но, по крайней мере, должно направить вас на правильный путь).

Если вы хотите, чтобы подклассы могли изменять значение переменной, а не только функцию, вам потребуется одно из следующих действий:

  1. Сделайте переменную protected (видимой только для класса и подклассов) и назначьте ее в конструкторе подкласса. или же,
  2. Предоставьте функцию установки в своем базовом классе и вызовите ее в своем конструкторе. Это можно защитить, если вы хотите ограничить доступ к подклассам и не разрешать классам вне пакета изменять его. или же,
  3. Просто переопределите функцию получения в вашем подклассе. (Кроме того, если вам не нужно, чтобы переменная была изменяемой, вы можете просто return "teacher";)
0
JasonTrue 27 Ноя 2022 в 06:39

Переменная с именем name в вашем подклассе скрывает переменную с таким же именем в суперклассе. См. https://docs.oracle.com /javase/specs/jls/se8/html/jls-8.html#d5e12172

Вы, вероятно, захотите иметь только одно поле name в суперклассе и хотите установить его при создании объекта:

class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}


class Teacher extends Person {
    public Teacher(String name) {
        super(name);
    }

    public static void main(String[] args) {
        Teacher teacher = new Teacher("teacher");
        System.out.println(teacher.getName());
    }
}
0
tgdavies 27 Ноя 2022 в 06:49