Значения абстрактного класса равны нулю после вызова супер - PullRequest
0 голосов
/ 31 октября 2018

У меня есть следующая программа:

public class Driver {

    public static void main(String[] args) {
        Animal dog = new Dog("larry");
        dog.speak();
    }

}

public abstract class Animal {

    private String name;

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

    public abstract void speak();
}

public class Dog extends Animal {

    private String name; // is this even needed?

    public Dog(String name) {
        super(name);
    }

    @Override
    public void speak() {
        System.out.println("I am " + name);

    }
}

При запуске этой программы печатается I am null, а это не то, что я хочу.

Почему бы просто не использовать переменную Animal, определенную name, и распечатать larry?

Как правильно это сделать?

Если я удаляю name из класса Dog, можно ли ссылаться на переменную имени Animal, сохраняя при этом private?

Если да, то как?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Вам не нужна переменная name in Dog; это отдельная переменная из переменной Animal. Конструктор Animal правильно инициализирует name в Animal, но метод speak в Dog ссылается на неинициализированную переменную name в Dog; переменная в Dog - это та, которая находится в области видимости внутри кода класса Dog. Удалите переменную name в Dog, чтобы избежать путаницы.

Но чтобы name был закрыт в Animal и доступ к нему в подклассе, предоставьте метод получения в Animal.

public String getName() { return name; }  // or protected

Тогда вы можете позвонить в Dog:

System.out.println("I am " + getName());

Выход:

I am larry
0 голосов
/ 31 октября 2018

Переменная name, используемая в

System.out.println("I am " + name);

определен в классе Dog. Он никогда не устанавливается, поэтому печатается null.

Нет необходимости определять name в Animal и Dog. Мое предложение будет:

  • удалить name из Dog
  • изменить видимость name в Animal на protected

Если вы хотите сохранить доступ к name как private, добавьте метод "getter" для name к Animal, таким образом:

public class Animal {
    private String name;
    public String getName() { return name; }
}
public class Dog {
    @Override
    public void speak() {
        System.out.println("I am " + getName());
    }
}
...