Создание экземпляра класса из main() по сравнению с созданием экземпляра из другого класса

Я хочу создать экземпляр дочернего класса в Java из родительского класса. Однако, когда я делаю это и пытаюсь вызвать родительский метод из конструктора дочернего элемента (с супер), возвращаемое поле равно нулю. Если бы я изменил это на создание экземпляра родителя из метода main(), поле возвращает ожидаемое значение (строку). Я не уверен, что здесь происходит, кто-нибудь может объяснить?

Основной класс:

public class MainFunc {

  public static void main(String[] args) {
    javaClass jv = new javaClass("Bobby");
    jv.makeJ2();
  }
}

Родительский класс:

public class javaClass {

  String name;

  public javaClass(){
  }

  public javaClass(String s) {
      setName(s);
  }

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

  public void makeJ2 (){
    javaClass2 jv2 = new javaClass2();
  }
}

Детский класс:

public class javaClass2 extends javaClass {

  String name;


  public javaClass2() {
    super();
    String superTitle = super.getName();

    System.out.println("HEY " + superTitle);
  }
}

Это возвращает:

HEY null

Вместо:

HEY Bobby

person Christophe Brown    schedule 18.06.2018    source источник
comment
Класс объекта, который используется для создания экземпляра другого объекта, не является его суперклассом.   -  person Robby Cornelissen    schedule 18.06.2018
comment
Каждая Java-программа проходит через основной метод. Он должен иметь основной метод.   -  person Gaurav Srivastav    schedule 18.06.2018
comment
Если вы хотите выйти как «ЭЙ, Бобби», вы должны сделать поле имени статическим «статическим строковым именем»; потому что статические переменные nun связаны с объектом, поэтому одно и то же значение не имеет разных объектов   -  person janith1024    schedule 18.06.2018
comment
@janith1024: неееет! Пожалуйста, не говорите новичкам делать вещи статичными. Кристоф: мой совет: используйте отладчик, чтобы проверить, какие поля являются частью каждого объекта, который вы создаете. Затем, возможно, снова пройдите учебник по Java.   -  person Nathan Hughes    schedule 18.06.2018


Ответы (6)


Вы не можете получить доступ к дочернему классу из родительского класса, дочерний класс унаследовал родительский класс, а не наоборот. Но вы можете сделать свою строку статической, чтобы она работала так, как вы хотите.

public class javaClass {

  static String name;
person Madhu    schedule 18.06.2018

С точки зрения дизайна, родитель никогда не должен создавать экземпляр дочернего класса. Это не похоже на человеческую систему воспроизводства. В мире OOPS дочерние классы должны объявлять своих родителей, и только эти дочерние классы знают о своих родителях, а не наоборот.

Несмотря на то, что намерение в опубликованном вопросе состоит в том, чтобы использовать Inheritance, это не происходит из-за запутанного кода. Вот как работает код:

  1. Test создает объект javaClass с именем jv. На данный момент jv имеет атрибут name, значение которого равно Bobby.
  2. вызывается метод makeJ2 jv, который создает очень new объект класса javaClass2 с именем jv2. Родительский класс этого самого объекта new НЕ имеет набора полей, и конструктору родительского класса ничего не передается. Следовательно, НЕТ отношения между родителем этого нового объекта jv2 и ранее созданным объектом jv, и поэтому:
  3. String superTitle = super.getName(); возвращает ноль, как и ожидалось

Точная проблема заключается в том, что дочерний объект не передает никакой информации для установки атрибутов родителя. Это может произойти из-за перегрузки supers или установки суперсвойств, но не только путем вызова super(). См. хорошее объяснение того, как наследование работает в java.

Пожалуйста, не используйте static только для того, чтобы заставить его работать

Наконец, я предлагаю также прочитать о композиции, так как это немного более предпочтительнее вместо наследования по некоторым веским причинам.

person gargkshitiz    schedule 18.06.2018

В вашем дочернем классе вы не перегружали конструктор для поля имени. Из перегруженного конструктора вы должны вызвать super(name);

person Gaurav Srivastav    schedule 18.06.2018

Выходные данные создаются по двум причинам.

  1. Поскольку вы вызвали super() в конструкторе javaClass2, а не super(String str)
  2. И поскольку родительский класс Java, экземпляр которого создается дочерним классом, отличается от того, из которого вы вызываете метод makeJ2(jv.makeJ2()).

Также ссылка на удар может помочь вам понять переопределение переменной экземпляра в java. Наследование Java переопределяет переменную экземпляра [дубликат]

person user7780    schedule 18.06.2018

Основываясь на своем прогрессе:

  1. Вы инициируете родительский класс:

    javaClass jv = new javaClass("Bobby");

  2. Атрибут имени javaClass будет "Бобби"

  3. Теперь время, когда вы звоните:

    jv.makeJ2();

  4. Он инициирует новый javaClass2:

    javaClass2 jv2 = new javaClass2();

  5. Это вызов super(); означает: javaClass() в javaClass не javaClass(String s)

  6. Итак, теперь ваш новый дочерний javaClass2 расширен из нового javaClass с новым именем (null).

Если вы хотите, чтобы javaClass2 печатал "Buddy", вам следует:

public javaClass2(String s) {
    super(s);
    String superTitle = super.getName();

    System.out.println("HEY " + superTitle);
  }
person Nguyễn Duy Hàn Lâm    schedule 18.06.2018

jv and jv2 are totally two different objects in the memory.
After all that is the fundamental meaning of "new" operator in Java.
you have used "new" operator twice in your code. 

Так что это означает, что у вас есть два совершенно разных объекта. имя jv установлено как «Бобби», но никто не установил имя для второго объекта jv2!

Imagine this:

class Manager extends Employee
{
....
public void setPMPCertified(boolean b)
{
...
}
}

//Generally Software engineers
class Employee
{
....
public void setName(String n)
{
.....
}
}

Manager m1 = new Manager();
Employee e1 = new Employee();
m1.setName("Robert");
m1.setPMPCertified(true);
e1.setName("Raja");

Robert is a manager. Raja is a software engineer. 

Это совершенно два разных данных (объекта) в памяти. Просто потому, что менеджер расширяет сотрудника, Роберт и Раджа не могут стать единым объектом. Посмотрите на тот факт, что мы дважды использовали оператор new для создания двух объектов. Обратите внимание, что у менеджера НЕТ метода setName. Он исходит от родителя (сотрудника). setPMPCertified применим только к менеджерам. нам все равно, сертифицирован инженер-программист по стандарту PMP или нет!! :)

person Jinnah    schedule 20.06.2018