一道关于继承的题

tmhk123 2010-09-25 08:47:48
class Foo{
public int a =3;
public void addFive(){
a+=5;
System.out.println("f");
}
}
class Bar extends Foo{
public int a =8;
public void addFive(){
this.a += 5;
System.out.println("b");
}
}
public class X{

public static void main(String []args){
Foo f =new Bar();
f.addFive();
System.out.println(f.a);
}
}


运行结果是: b
3

为什么f.a是3呢?
...全文
148 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ETCentury 2010-10-13
  • 打赏
  • 举报
回复
哈哈,好东西,学习了~!
clariones 2010-09-26
  • 打赏
  • 举报
回复
main函数中的这段代码:
Foo f =new Bar(); <====这里创建了一个子类实例,但是是一个父类的引用
f.addFive(); <====根据继承原理,这里调用了子类的重载函数
System.out.println(f.a); <====这里使用的是对象的引用,而前面声明成了父类,所以按照父类型查找,查找到了父类的成员a

详细解释如下
第一行:
在这行代码里,创建实例的过程如下:
首先创建父类的实例,所以有实例f, f.a=3;
然后创建子类声明的部分,因为子类也声明了一个a,与父类的声明相同,这样会“覆盖”父类的a,所谓覆盖,就是在子类中,除非用super.a,否则总是引用子类的a。
最后的结果就是,内存中有一个对象,有两个成员 super.a=3, a=8, 有两个函数super.addFive,和 addFive.

第二行:
在这行代码里,调用的函数,查找虚函数表,结果得到this.addFive
这个函数会调用 this.a += 5, 根据上面的结果,不是操作super.a, 所以super.a还是3

第三行:
打印时,这是一个 父类引用,所以,a就是 Foo.a,因为在第二行中改变的是Bar的this.a,而Foo.a没有改变。

没有虚成员表,所以成员没有RTTI,结果就这样了。 要说道理,其实也没啥道理,语言的语法定义就这么定义了。 语言是一种工具,和天然存在的东西不同。
KingWolfOfSky 2010-09-26
  • 打赏
  • 举报
回复
这个涉及到继承过程中类变量的隐藏方法的重写和隐藏(此处是重写)以及RTTI

在这个例子中Bar的addFive()重写了父类的addFive(),编译时确定了a的类型为f(Foo).a

楼主看看这个例子及输出可以加强理解

class Foo{
public int a =3;
static public void addOne(){
System.out.println("f");
}
public void addFive(){
a+=5;
System.out.println("f");
}
}
class Bar extends Foo{
public int a =8;
static public void addOne(){
System.out.println("b");
}
public void addFive(){
this.a += 5;
System.out.println("b");
}
}
public class X{

public static void main(String[] args) {
Foo f =new Bar();
f.addOne();
f.addFive();
System.out.println(f.a);
System.out.println(((Bar)f).a);
}
}
/* Output:
* f
* b
* 3
* 13
*/
hjjk123 2010-09-25
  • 打赏
  • 举报
回复
其实都是调用的Foo的方法和属性 只是 调用方法的时候 ‘中断’ 由于多态的特性 所以 调用的是子类的方法
hjjk123 2010-09-25
  • 打赏
  • 举报
回复
方法的访问支持多态

然而 属性是根据对象的所属来访问的。。。。
zcy9979420 2010-09-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 littlejp 的回复:]

父引用.属性时 只能拿到父对象的属性,不会取出子对象的。
[/Quote]
zhuyouyong 2010-09-25
  • 打赏
  • 举报
回复
ding[Quote=引用 1 楼 littlejp 的回复:]
父引用.属性时 只能拿到父对象的属性,不会取出子对象的。
[/Quote]
  • 打赏
  • 举报
回复
属性会访问父类的。方法会访问子类的,如果子类重写了父类的方法。
littleJP 2010-09-25
  • 打赏
  • 举报
回复
父引用.属性时 只能拿到父对象的属性,不会取出子对象的。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧