A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© s476596497 中级黑马   /  2014-1-20 10:45  /  1360 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class TEST22 {
    public static void main(String args[]){
        Foo f = new Bar();
        f.addFive();
        System.out.println(f.a);
    }
}
class Foo {
    public int a = 3;
    public void addFive() {
        a += 5; System.out.print("f "); }
}
class Bar extends Foo {
    public int a = 8;
    public void addFive() {
        this.a += 5; System.out.print("b " ); }
}


为什么输出是 “b 3”?
这程序的运行顺序究竟是怎样的?
Bar f = new Bar()或者Foo f = new Foo()我知道,但是Foo f = new Bar()会怎样运行呢?把Bar类转换成Foo类?那参数和函数会运行哪个?

5 个回复

倒序浏览
具体分析 Foo f = new Bar(); 父类类型指向子类对象 f.addFive();方法编译时看右边 打印了一个b f.a而变量是编译时看左边 左边是父类类型所以打印了一个3 父类的a变量赋值是3
回复 使用道具 举报
本帖最后由 dapeng111 于 2014-1-20 11:31 编辑
  1. //将你的代码稍做改动
  2. public class Test22 {
  3.     public static void main(String args[]){
  4.         Foo f = new Bar();   //这里用的是多态,父类引用指向了子类对象
  5.         f.addFive();         //在这里子类中已经对方法进行了覆写,以子类中的方法为准所以会输出b和加过后的值a1=13
  6.         System.out.println("\na2 = "+f.a); //可是在这里,变量和方法不同,f只认识父类中定义的变量,所以输出的是父类中的变量a2=3
  7.         Bar b = (Bar)f;                    //如果想输出子类中的可以进行一个父类型强制转化为子类型就可以了,在下面会输出a3 = 13
  8.         System.out.println("a3 = "+b.a);
  9.     }
  10. }
  11. class Foo
  12. {
  13.     public int a = 3;
  14.     public void addFive()
  15.     {
  16.         a += 5;
  17.         System.out.print("f ");
  18.     }
  19. }
  20. class Bar extends Foo
  21. {
  22.     public int a = 8;
  23.     public void addFive()
  24.     {
  25.         a += 5;
  26.         System.out.println("b " );
  27.         System.out.print("a1 = "+ a);
  28.     }
  29. }
复制代码

补充说明一下:
1、把Bar类转换成Foo类?
不是把Bar类转换成Foo类,变的只是一个引用。父类引用指向了子类对象,在堆中建立的还是一个子类的对象,只不过是父类的名称指向的。
2、那参数和函数会运行哪个?
运行的时候运行的是子类的对象,并调用子类的相关函数。只是在遇到同名的变量时,不能正学识别出来子函数中的同名的变量,需要经过类型转换,将父类的引用转换为子类而已。希望能帮到你!
回复 使用道具 举报
父类引用指向子类对象,子类复写了addFive方法,所以主函数调用的是子类方法,但是父类引用调用成员变量时,会先看看父类有没有,如果有,调用的就是父类的成员变量,所以打印结果是子类方法中的 b  和父类中int类型a成员的值3
回复 使用道具 举报
子类addFive()覆盖了父类的addFive()
回复 使用道具 举报
当一个引用类型的变量若声明为父类的类型,但实际上引用的是子类的对象(多态情况):
此时该变量不能再访问子类中自己特有的字段和方法;
若子类覆写了父类的方法,那么此时通过变量访问到的方法,实际上是子类的方法;
这是用到的知识点
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马