从main()实例化一个类与另一个类实例化

时间:2018-06-18 04:29:59

标签: java oop parent-child

我想在父类中用Java实例化一个子类。但是,当我这样做,并尝试从子的构造函数(使用super)调用父方法时,返回的字段为null。如果我将其更改为从main()方法实例化父级,则该字段将返回预期的方式(String)。我不知道这里发生了什么,有人可以解释一下吗?

主要课程:

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

6 个答案:

答案 0 :(得分:1)

设计明智,父母不应该实例化子类。它不像人类的生殖系统。在OOPS世界中,儿童班需要申报自己的父母,只有这些儿童班知道他们的父母而不是反过来。

即使发布的问题中的意图是使用Inheritance,但这并不是由于复杂的代码而发生的。这就是代码的运行方式:

  1. Test创建名为javaClass的{​​{1}}个对象。此时jv有一个属性jv,其值设置为name
  2. 调用
  3. Bobby的{​​{1}}方法,这会创建类jv的非常makeJ2个对象,名为new。这个非常javaClass2对象的父类没有任何字段集,也没有任何内容传递给父类的构造函数。因此,此新对象jv2的父级与先前创建的new对象之间没有任何关系,这就是原因:
  4. jv2按预期返回null
  5. 确切的问题是子对象没有传递要设置的父属性的任何信息。这可以通过重载jv或通过设置超级属性而不仅仅是通过调用String superTitle = super.getName();来实现。查看good explanation of how inheritance works in java

    Please do not use static just to make it work

    最后,我建议阅读有关合成的内容,因为这比继承更多preferable,原因有些充分。

答案 1 :(得分:1)

您无法从父类访问子类,子类继承了父类,而不是其他方式。但是你可以让你的String静态,让它以你想要的方式工作。

public class javaClass {

  static String name;

答案 2 :(得分:0)

在您的子类中,您没有为name字段重载构造函数。从重载的构造函数中,您应该调用super(name);

答案 3 :(得分:0)

生成的输出有两个原因。

  1. 因为你在javaClass2构造函数中调用了super()而不是super(String str)
  2. 因为子类实例化的父java类与您调用方法makeJ2(jv.makeJ2())的类不同。
  3. 此外,blow链接可以帮助您了解java中的实例变量覆盖。 Java inheritance overriding instance variable [duplicate]

答案 4 :(得分:0)

根据您的进度:

  1. 您启动父类:

    javaClass jv = new javaClass("Bobby");

  2. javaClass名称属性将为“Bobby”

  3. 现在打电话给你:

    jv.makeJ2();

  4. 它将启动新的javaClass2:

    javaClass2 jv2 = new javaClass2();

  5. super();而非javaClass()

  6. 中调用javaClass均值:javaClass(String s)
  7. 所以现在你的新子javaClass2是从新的javaClass扩展而来的,它的名字是new(null)。

  8. 如果你想让javaClass2打印“好友”,你应该:

    public javaClass2(String s) {
        super(s);
        String superTitle = super.getName();
    
        System.out.println("HEY " + superTitle);
      }
    

答案 5 :(得分:0)

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的名称设置为“ Bobby”,但没有人为第二个对象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认证!! :)