Вызов родительского метода в дочернем классе возвращает нулевое значение - PullRequest
0 голосов
/ 16 февраля 2019

Я пытаюсь отобразить значение переменной из родительского класса, используя родительский метод, но из дочернего класса.

public class A {
    public static void main(String[] args) {
        Parent p1 = new Parent();
        p1.input();
    }
}
class Parent {
    private String name;
    public void setName(String newName) {
        name = newName;
    }
    public String getName() {
        return name;
    }
    public void input() {
        String q = "hi";
        setName(q);
        Child c1 = new Child();
        c1.input();
    }
}
class Child extends Parent {
    public void input() {
        System.out.print(super.getName());
    }
}

Я ожидал, что он выдаст hi, но вместо этоговыход null.Вещи, которые я пробовал:

  1. Использование getName() вместо super.getName() в дочернем классе.
  2. Использование Parent p2 = new Parent(); и затем p2.getName() в дочернем классе.
  3. Использование protected String name; в родительском классе.

Кажется, что ничего из этого не работает;все они все еще выводят null в конце.Помощь

Ответы [ 5 ]

0 голосов
/ 18 февраля 2019

Просто чтобы дать вам еще один маленький образец для работы:

public class main { 
    public static void main(String[] args) { 
        Parent p1 = new Parent(); 
        p1.input();
        Child c1 = (Child)P1; //this is a type cast, which is possible due to what is known as polymorphism
        c1.input();
    } 
}

class Parent {

    private String name;

    public void setName(String newName) {
        name = newName; 
    } 

    public String getName() { 
        return name; 
    } 

    public void input() { 
        String q = "hi"; 
        setName(q); 
    } 
} 

class Child extends Parent { 
    public void input() { 
        System.out.print(super.getName()); 
    } 
}

В этом крошечном образце (основанном на вашем собственном) вы создаете только один экземпляр родительского элемента.Затем вы вводите cast в переменную c1 как Child.Поэтому, когда вы звоните input () на это.Он использует реализацию из класса Child, а не из parent.

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

0 голосов
/ 16 февраля 2019

После комментария, который я оставил, форматирование кода в комментариях очень ограничено.Таким образом, основная проблема заключается в том, что ребенку не обязательно иметь родителя.Ребенок должен иметь точный желаемый объект в качестве родителя.Обычно это делается с помощью конструктора.Поэтому я бы сделал дочерний класс следующим образом:

class Child extends Parent {
    private Parent parent;

    public Child(Parent parent) {
        this.parent = parent;
    }

    public void input() {
        System.out.print(parent.getName());
    }
}

Тогда в родительском классе вы получите:

public void input() {
    String q = "hi";
    setName(q);
    Child c1 = new Child(this);
    c1.input();
}
0 голосов
/ 16 февраля 2019

Вы создаете дочерний объект в родительском объекте, и вы устанавливаете текущий поле имени родительского объекта, но не родительский объектдочерний, что означает, что у вас создается более одного родительского объекта - один, чье поле имени устанавливается, а другой (родительский объект), чье поле имени никогда не устанавливается, но проверяется.

В качестве дополнительного бита родительский класс не должен заниматься такими вещами.Это должен быть ребенок "агностик".

0 голосов
/ 16 февраля 2019

Это происходит как новый и отдельный Child объект, созданный, когда вы сделали Child c1 = new Child();, который наследует свойство name от родительского класса Parent, унаследованное свойство которого name не установлено и равно null.p1 в main - это совершенно другой экземпляр, значения которого не используются совместно с экземпляром c1.

Использование getName () вместо super.getName () в дочернем классе.

Обе они приведут к null, поскольку name наследуется от родительского класса Parent и не инициализируется.Объект Parent, который вы инициализировали в методе main, является совершенно другим экземпляром, свойства которого не упоминаются экземпляром child в методе input.

Using Parent p2= новый родитель ();а затем p2.getName () в дочернем классе.

Снова вы создаете отдельный экземпляр Parent, и поскольку вы не инициализировали значение name экземпляра p2 p2.getName() вернет ноль.

Использование защищенного строкового имени;в родительском классе.

protected просто является модификатором доступа, он не поможет вам инициализировать свойство name, унаследованное от класса Parent.

Вот это визуально: enter image description here

0 голосов
/ 16 февраля 2019

Когда вы пишете: "child c1 = new child ()", вы создаете совершенно новый экземпляр.Этот новый экземпляр имеет значение null для своего поля name: конструктора child там нет, поэтому вы получаете конструктор по умолчанию (который вызывает конструктор родительского класса и ничего больше).Ваш родительский класс также не имеет конструктора, поэтому он также ничего не делает, что оставляет поле name с его значением по умолчанию null.

Затем вы вызываете метод input в этом экземпляре.Поскольку фактический тип этого экземпляра - child, выполняется метод input(), определенный в вашем классе child, который печатает значение поля name, которое равно null.

Даесть ДРУГОЙ экземпляр (типа parent), у которого для поля name установлено значение "Привет", но вы не вызываете метод input для этого экземпляра.Вы вызываете input метод экземпляра, который вы создаете в строке child c1 = new child();.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...