这是指在子类对象上调用非重写方法时的内容?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这是指在子类对象上调用非重写方法时的内容?相关的知识,希望对你有一定的参考价值。

请考虑以下代码:

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());打印printClassName
  4. 如果您对#2的答案是子类的对象,那么为什么printClassName中的第一行打印"I am Person"
答案

您将变量声明为Employee类型

this.className

指的是该类中的className

this.getClass().getSimpleName()

this.getClass()返回类Employee,因为这就是你如何声明变量,这就是getSimpleName()返回“Employee”的原因

另一答案

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

(可能已知。)

class Employee extends Person { // Manner to change the super field
    Employee() {
        className = "Employee";
    }
}
  1. new Employee()创建一个包含两个className字段的对象。它调用超级构造函数,执行字段初始化,并执行其余的构造函数代码。
  2. this总是唯一的对象,可能是某些儿童类。所以Person.this实际上可能是一名员工。
  3. 对于Employee对象,在Person中的this.className只会访问Person字段,因为字段没有继承。相比之下,方法xxx()将称呼孩子最多的方法。

以上是关于这是指在子类对象上调用非重写方法时的内容?的主要内容,如果未能解决你的问题,请参考以下文章

8. 多态

(十八)多态

Java实例化对象时的初始化

Java中方法重写和方法重载

Java重写重载的区别

JAVA SE中方法重载和方法重写及数据库中子程序的重载