Java 这是指在子类对象上调用非重写方法时发生的情况?

Java 这是指在子类对象上调用非重写方法时发生的情况?,java,inheritance,name-hiding,Java,Inheritance,Name Hiding,考虑以下代码: 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

考虑以下代码:

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();
    }

}
我有几个问题

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

  • 如果创建了两个对象,在子类对象上调用非重写方法时,哪个对象负责?换句话说,
    this
    在非重写方法中指的是什么?隐藏的超类对象还是子类对象

  • 如果#2的答案是超类的隐藏对象,那么为什么上面的代码会为
    System.out.println(“I am”+getClass().getSimpleName())打印
    “我是员工”
    内部
    printClassName

  • 如果#2的答案是子类的对象,那么为什么
    printClassName
    中的第一行打印
    “我是人”


  • 将变量声明为type
    Employee

    this.className
    
    指该类中的
    className

    this.getClass().getSimpleName()
    

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

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

    (可能已经知道了。)

  • newemployee()
    创建一个包含两个类名字段的对象。它调用超级构造函数,进行字段初始化,并执行其余的构造函数代码

  • 始终是唯一的对象,可能是某个子类的对象。所以一个人,这可能是一个雇员

  • 四,
    this.className
    Person for Employee对象将直接访问Person字段,因为字段没有继承。相反,方法
    xxx()
    将调用子most方法


  • 我坚信
    这个
    总是指调用方法的对象。但是你能解释一下为什么打印类名的第一行打印它打印的内容吗?超类并不真正了解子类(不同于其他方式)。当您输入'this.className'并在该类中找到该变量时,即为'done deal'。您可能将它隐藏在子类中,但您在父类中调用它,在父类中它仍然可以访问隐藏的变量。(是的,它引用的是当前实例),这是使用相同名称创建新变量时得到的结果。(为什么不鼓励这样做)
    class Employee extends Person { // Manner to change the super field
        Employee() {
            className = "Employee";
        }
    }