0

考虑以下代码:

class Person {
    String className = "Person";

    void printClassName () {
        System.out.println("I am " + this.className);
        System.out.println("I am " + this.getClass().getSimpleName());
    }
}

class Employee extends Person {
    // intentionally hiding this field
    String className = "Employee";
}

public class App {
    public static void main(String[] args) {
        Employee raghu = new Employee ();
        raghu.printClassName();
    }

}

我有几个问题。

  1. 创建子类的对象时,实际创建了多少个对象?只有一个,通过引入子类中定义的新属性来扩展超类的属性?或者两个,我们可以访问的子类对象和一个超类对象,它们的存在对我们来说是隐藏的?

  2. 如果创建了两个对象,当在子类对象上调用非覆盖方法时,哪个对象负责?换句话说,this非覆盖方法内部指的是什么?隐藏的超类对象还是子类对象?

  3. 如果您对#2 的回答是超类的隐藏对象,那么为什么上面的代码会打印"I am Employee"System.out.println("I am " + getClass().getSimpleName());inside printClassName

  4. printClassName如果您对#2 的回答是子类的对象,那么为什么打印里面的第一行"I am Person"

4

2 回答 2

1

您将变量声明为类型Employee

this.className

className那个类中的。

this.getClass().getSimpleName()

this.getClass()返回 class Employee,因为这就是您声明变量的方式,这就是getSimpleName()返回“Employee”的原因

于 2018-02-15T14:04:34.453 回答
0

子类 Employee 中的字段 className 是额外的第二个字段,与 Person 中的字段 className 同名;这称为阴影字段没有继承。

(应该是已知的。)

class Employee extends Person { // Manner to change the super field
    Employee() {
        className = "Employee";
    }
}
  1. new Employee()创建一个包含两个 className 字段的对象。它调用超级构造函数,进行字段初始化,并执行构造函数的其余代码。

  2. thisalways 是唯一的对象,可能是某个子类。所以一个 Person.this 可能实际上是一个 Employee。

  3. 4.this.className在 Person 中,Employee 对象只会访问 Person 字段,因为字段没有继承。相反,该方法xxx()将调用 child most 方法。

于 2018-02-15T14:16:24.433 回答