【问题标题】:Inherited Object printing as null in JavaJava中继承的对象打印为null
【发布时间】:2014-04-03 23:11:18
【问题描述】:

我们被指示在父类 Person 中将字符串“名称”定义为私有。但是,当我尝试显示 Person 和 Employee 对象的名称时,Employee 名称被打印为“null”。我不允许将“名称”定义为公开的。

人物类:

public class Person {

private String name;
public int weight, height;

public Person() {}

public Person(String name) {

    this.name = name;
}

public String getName() {

    return name;
}


public String toString() {

    return this.getName() + ", your height is " + height + " and your weight is "
            + weight;
}

员工类:

public class Employee extends Person {

private int id;

public Employee(String name, int id) {
    this.id = id;
    this.name = name;
}

public int getID() {
    return id;
}

}

主类:

Person a1 = new Person("Thomas");
    a1.height = 70;
    a1.weight = 160;
    Person a2 = new Employee("Rebecca", 6543);
    a2.height = 65;
    a2.weight = 128;
    Person a3 = new Employee("Janice", 8765);
    a3.height = 60;
    a3.weight = 120;
    Person[] arr = new Person[] {a1, a2, a3};
    Person a;
    for (int i = 0; i < arr.length; i++) {
        a = arr[i];
        System.out.println(a.toString() + "; your BMI is: " + a.calcBMI());
    }
    Person.countEmployees(arr);

输出:

Thomas,你的身高是 70,体重是 160;您的 BMI 为:22.955102040816328 null,你的身高是65,你的体重是128;您的 BMI 为:21.297988165680472 null,你的身高是60,你的体重是120;你的 BMI 是:23.433333333333334

我通过电子邮件询问了我的教授,她说因为 toString() 是在父类 Person 中定义的,所以应该不会发生此错误。我的语法错了吗?逻辑错了?

【问题讨论】:

  • 你能用protected吗?
  • 这如何编译?你的编译器在Employee 类中的this.name = name; 上不会出错吗?
  • @EmersonFarrugia 是的,当我包含“this.name=name”时它确实会出错;我把它拿出来测试,然后打印空对象

标签: java inheritance private


【解决方案1】:

问题是您的Employee 构造函数正在调用默认的Person 构造函数(该调用由编译器自动注入,因为定义了默认构造函数。您可以在Person 中删除该默认构造函数,然后您'会看到它没有编译)。

您应该调用在 Employee 构造函数中接收名称的构造函数,而不是设置属性(不应该编译,顺便说一句)

public Employee(String name, int id) {
  super(name);
  this.id = id;
}

【讨论】:

  • 是的,它只有在我取出“this.name = name;”时才编译
【解决方案2】:

我不确定你的这个类是如何编译的

public class Employee extends Person {

  private int id;

  public Employee(String name, int id) {
      this.id = id;
      this.name = name;
  }
}

当您说 this.name = name 并且 Person.name 是私有的时,如果您没有在 Employee 类中定义另一个名为 name 的变量,则不应编译。

回到你的问题,你需要在 Employee 构造函数中调用 Person 的构造函数,像这样

public class Employee extends Person {

  private int id;

  public Employee(String name, int id) {
      super(name);
      this.id = id;
  }
}

【讨论】:

    【解决方案3】:

    您应该删除 Employee 构造函数中的 this.name = name; 行,并添加对 super(name); 的调用作为同一构造函数的第一行。

    【讨论】:

      【解决方案4】:

      这是因为它在 Person 类中是私有的,因此您无法在 Employee 类中访问它,因此您不能直接从那里设置它。

      改变这个

      public Employee(String name, int id) {
          this.id = id;
          this.name = name;
      }
      

      为此,它调用你需要设置名称的构造函数:

      public Employee(String name, int id) {
          super(name);
          this.id = id;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多