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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 廖成 中级黑马   /  2013-1-27 11:37  /  1738 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

由这段代码:

  1. class A {
  2.     public A() {
  3.         printValue();
  4.     }
  5.     public void printValue() {
  6.         System.out.println("A_printValue");
  7.     }
  8. }

  9. class B extends A {
  10.     public void printValue() {
  11.         System.out.println("B_printValue");
  12.     }

  13.     public void getField() {
  14.         System.out.println("B_getField");
  15.     }
  16. }

  17. class Test {
  18.     public static void main(String[] args) {
  19.         A a = new B();
  20.         a.printValue();
  21.         ((B)a).getField();
  22.     }
  23. }
复制代码
我的问题是:
对象a的实际类型,这里是指A,还是B ?
如果是A的话,a.printValue(),调用的是B中的方法,这里的动态绑定顺序又是怎么回事?
这里和A()中调用printValue(),调用B中的方法,是否是相同原因?

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

4 个回复

倒序浏览
A a = new B(); //在A类型的引用了一个B类型的对象。
a.printValue(); //打印的是B类中的方法,因为B类中覆盖了A类的printValue()
((B)a).getField();//这个也是打印的B类中的方法,



class A {
    public A() {
        printValue();// A a = new B(); 用于初始B的时候会先初始父类A,
                             //由于传进来的是B的this对象,又由于B类复写了A类的方法,
                                         //所以这里调用的是B类的方法。
    }
    public void printValue() {
        System.out.println("A_printValue");
    }
}

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
多态的体现
        父类的引用指向了自己的子类对象。
        父类的引用也可以接收自己的子类对象。
多态的前提
        必须是类与类之间有关系。要么继承,要么实现。
        通常还有一个前提:存在覆盖。

在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法

所以
A a = new B();
        a.printValue();   //  一定执行的是子类的已经复写完的方法
        ((B)a).getField();   //多态的弊端:
        虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员  所以这时得强转成 子类对象 调用子类特有的 getField()

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
1. a的实际类型是B,父类是A。
2. 因为B继承自A,而且B类重写了A类的printValue(),所以用A去实例一个B对象时,程序会先去执行父类的构造方法,执行A类里printValue()方法,但是,由于这个方法已经被B类给重写,所以会执行B类里的printValue()。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
A a = new B();//这是使用了java中的多态,因为B类继承了A,所以a对象指向的是B的实例。
a.printValue();//调用的是B类中的方法,因为a的对象指向的是B的实例,所以打印的是B_printValue,
在上面两句话中,体现了多态中的向上转型,A的对象指向B的实例,B向上转型成了A,
((B)a).getField();//因为知道a指向的实例是B,所以可以对a对象进行向下转型,((B)a)相当于B b = new B();
在多态中,向下转型是有风险的,如果你不知道a的对象是指向B的,那么向下转型会出现类型转换异常错误

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马