返回信息流class A {
public String string="A";
public void print() {
System.out.println("call A print");
};
}
class B extends A {
public String string="B";
public void print() {
System.out.println("call B print");
};
}
public void test(){
B b = new B();
b.print();
System.out.println(b.string);
A a = b;
a.print();
System.out.println(a.string);
}
调用test()函数输出的结果是:
call B print
B
call B print
A
不是说父类的引用看不见子类新增的东西吗?
为什么第三行输出。。。
这是一条镜像帖。来源:北邮人论坛 / java / #47787同步于 2016/1/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
Java和c++的面向对象对比了下,我凌乱迷惘了
ailuai
2016/1/27镜像同步16 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
学习了
【 在 Lamperouge 的大作中提到: 】
: 因为子类重写了print方法,父类引用看不到子类新增的东西,那个貌似是静态绑定,比如成员变量啥的,如果说错了的话麻烦纠正下
【 在 ailuai 的大作中提到: 】
: class A {
: public String string="A";
: public void print() {
: ...................
成员变量不会像方法那样被覆盖(override)。在子类中定义成员变量,如果和父类的某个成员变量叫同一个名字,只是“隐藏”(hide)父类中的成员。
JLS 8.3: If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.
访问成员变量的时候,看的是表达式的静态类型,而不是它指向的对象的实际类型。比如a这个变量的类型是A,那么a.string就是A的string,就算a指向的对象实际上是B,也是访问A的string。
JLS 15.11.1:
The type of the Primary 【就是a.string里的那个a】 must be a reference type T, or a compile-time error occurs
* If the field is not static:
* ...
* If the field is not final, or ..., then the result is a variable, namely the named member field in type T found in the object referenced by the value of the Primary.
嗯,学习了,我只是疑问第三行的输出,为什么如果是在子类中增加一个方法,父类引用看不见,但是重写的却看得见。。。看了c++以后有点乱了
【 在 nuanyangyang 的大作中提到: 】
: 成员变量不会像方法那样被覆盖(override)。在子类中定义成员变量,如果和父类的某个成员变量叫同一个名字,只是“隐藏”(hide)父类中的成员。
:
: ...................
Java中所有函数都是虚函数调用
【 在 ailuai (ailuai) 的大作中提到: 】
: 嗯,学习了,我只是疑问第三行的输出,为什么如果是在子类中增加一个方法,父类引用看不见,但是重写的却看得见。。。看了c++以后有点乱了
【 在 ailuai 的大作中提到: 】
: 哇,学习了,大神,推荐一本书Java进阶点的书我看看吧
还是推荐这个 https://docs.oracle.com/javase/tutorial/