gpt4 book ai didi

java - 为什么子类的私有(private)变量存储在父类(super class)类型变量中时仍被保留?

转载 作者:行者123 更新时间:2023-12-02 00:07:28 26 4
gpt4 key购买 nike

我一定错过了继承中的一些基本内容,因为它对我来说没有意义。

给定这两个类:

class Person
{
private String name;
}

class Student extends Person
{
private String degree;
}

为什么可以创建一个新的 Student 对象,将其存储在 Person 类型变量中,并且仍然能够保留变量 String Degree 并有权访问它?

Person p = new Student("John", "Master's");

我认为可以使用上面的初始化,因为 p 除了 name 之外不会有任何变量,因为 Person 变量不能包含 level 变量,因此它是合法的 - 但当您这样做时,level 并不存在于 p 中。

这就是我认为相反是非法的事实背后的原因
(Student s = new Person("John");) - 因为这样 s 将不会初始化其其他变量 (level)。

最佳答案

具有对父类(super class)型的引用类型的变量可以保存对子类型实例的引用。将子类型实例分配给变量不会以任何方式更改实例;它只是扩大了引用的类型。所有实例数据仍然存在,并且可以通过向下转换来检索。也就是说,

Student s = new Student("John", "Master's");
Person p = s; // no cast needed for a widening conversion

与以下内容完全相同:

Person p = new Student("John", "Master's");
Student s = (Student) p; // cast required for a narrowing conversion

编辑也许这将有助于澄清事情。假设有 Person 的第二个子类:

class Teacher extends Person
{
private String department;
}

现在你可以这样做:

Person p = new Teacher("Fred", "Physics");
Teacher t = (Teacher) p;

但是如果您后来尝试这样做:

p = new Teacher("Fred", "Physics");
Student s = (Student) p; // Error!

你会得到一个ClassCastException因为在程序中的此时,p 现在是对不是 Student 的对象(Teacher 的实例)的引用。

这是一个类比。用英语,你可能会说,“我有一只宠物”。这没有说明动物的类型。 (例如,您无法知道宠物是否吠叫。)另一方面,如果您说“我有一只宠物狗”,那么询问它是否对陌生人吠叫是有意义的。关键点是:将您的宠物称为动物并不会改变它是(或不是)狗的事实。 Java 引用也发生了完全相同的情况——使用更通用的(例如基类)引用类型来存储对象引用不会改变对象本身的性质。您失去了该对象的详细信息知识,但这些详细信息仍然存在。

重复我在评论中提出的观点:在 Java 中,你永远不会将对象分配给变量;而是将对象分配给变量。您只需将引用分配给对象。或者,换句话说,你的变量都不是对象。

关于java - 为什么子类的私有(private)变量存储在父类(super class)类型变量中时仍被保留?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13554757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com