在JAVA中,当基类的引用变量指向子类的对象时,内部会发生什么
在JAVA中,当基类的引用变量指向子类的对象时,内部会发生什么,java,class,object,inheritance,reference,Java,Class,Object,Inheritance,Reference,ABC a1=new XYZ() 其中XYZ扩展了ABC 数据类型告诉我们变量将包含什么。 让我困惑的是,怎么可能要求引用变量指向它不是变量的东西 即使我们能做到,它有什么好处 它是如何在内部工作的。当我们写作时 ABC a1=new XYZ()此模式为您提供了灵活性 排序算法示例: private List<Integer> myCollectionToSort = new ArrayList<>(); 就这样想吧: ABC a1 = new XYZ(); a1.a
ABC a1=new XYZ()代码>
其中XYZ扩展了ABC
数据类型告诉我们变量将包含什么。
让我困惑的是,怎么可能要求引用变量指向它不是变量的东西
即使我们能做到,它有什么好处
它是如何在内部工作的。当我们写作时
ABC a1=new XYZ()代码>此模式为您提供了灵活性
排序算法示例:
private List<Integer> myCollectionToSort = new ArrayList<>();
就这样想吧:
ABC a1 = new XYZ();
a1.a = 5;
a1 -> aaaaxxxx (reference a1 points to a structure containing 4 bytes a and 4 bytes x)
鉴于这两类:
class ABC {
int a;
public void getA() {return a;}
}
class XYZ extends ABC {
int x;
public void getX() {return x;}
}
编译器将这两个类添加到一起:
class XYZ {
int a;
int x;
public void getA() {return a;}
public void getX() {return x;}
}
如果存在除public之外的任何其他可见性参数,如果函数名或变量名之间存在重叠,那么它就要稍微复杂一点,但基本上就是这样。在内存中,首先是基类的内容,然后是派生类的内容
在内存中,现在有一些类似这样的类(每个字母代表一个字节):
因此,当您访问以下内容时:
ABC a1 = new XYZ();
a1.a = 5;
a1 -> aaaaxxxx (reference a1 points to a structure containing 4 bytes a and 4 bytes x)
然后,编译器将此a1视为一个ABC,这是有效的,因为两者的成员变量a都位于对象的前四个字节中
但它不会让你做这样的事情:
ABC a1 = new XYZ();
a1.x = 5;
这是因为ABC的所有对象或其任何派生类型的前四个字节中都有成员变量a,但并非所有对象的后四个字节中都有x。只有XYZ的对象在第二个四字节中有x。因此,编译器在这里抛出一个错误
所以如果你写:
ABC a1 = new XYZ();
内部看起来是这样的:
ABC a1 = new XYZ();
a1.a = 5;
a1 -> aaaaxxxx (reference a1 points to a structure containing 4 bytes a and 4 bytes x)
由于a1属于声明的类型ABC(以及动态类型XYZ),因此只能访问ABC中出现的成员变量(以及相应的字节)。因此,尽管有两个包含8字节的成员变量,编译器只允许访问第一个成员变量(a),而不允许访问第二个成员变量。“要指出的是,它不是“->的变量,是的。这是一个非常广泛的问题。例如,请阅读关于多态性的文章,看看有哪些可能的好处。@ArnaudDenoyelle如何?@BartoszKP哦,是的,我可以设法消化这些好处。但我想知道会发生什么internally@SrujanBarai为了说明为什么XYZ
是ABC
,我完成了我的回答。