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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 贾飞雨 中级黑马   /  2012-6-22 19:45  /  1839 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 yufeiant 于 2012-6-22 20:39 编辑

/*有个很纠结的问题问大家


在毕老师的视频中,举到的那个毕老师和毕姥爷的
说毕老师化妆为毕姥爷,然后去替毕姥爷教书,但是不知道教的什么,所以教java
然后我就想到,在多态的应用中,
比如*/
abstract class Fu
{
         abstract void teach();
               
}
class Zi extends Fu
{
        void teach()
                {
                        System.out.println("教java");
                }
}
class  Demo
{
        public static void main(String [] args)
                {
                        Fu f = new Zi();
                        f.teach();//在这里打印输出的结果是"教java".然后我就郁闷了,
                        //不是说父类只能调用父类吗?这个编译就应该报错的啊?怎么会调用子类的方法呢?
                }
}

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
本帖最后由 丁二跃 于 2012-6-22 20:00 编辑

Fu f = new Zi();
  f.teach();//

虽然f被声明成Fu 但是他的本质还是Zi

这里你用子类来new一个实例 把他赋给声明成父类的  f
f  就成了一个上转型对象,他可以操作子类里继承于父类的成员变量和方法,但是不能操作子类新添加的成员变量和方法。

评分

参与人数 2技术分 +1 黑马币 +8 收起 理由
黄奕豪 + 1 赞一个!
贾飞雨 + 8 赞一个!

查看全部评分

回复 使用道具 举报
在多态中,父类引用指向了子类对象,但是他只能看到子类从父类继承过来的那部分,这就是多态,也就是迟绑定,因为父类对象指向了子类对象,并且子类对象重写了父类继承过来的方法,所以父类对象知道要调用什么方法———就是子类继承过来并重写了的方法!

评分

参与人数 2技术分 +1 黑马币 +8 收起 理由
黄奕豪 + 1 赞一个!
贾飞雨 + 8 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 黄连兵 于 2012-6-22 20:05 编辑

记住毕老师的话吧,成员函数(静态方法除外)在多态调用时,编译看左边,运行看右边。
用接口或者父类的引用,运行的时候动态调用具体子类的方法,实现子类所覆写的功能,这是多态的最主要,最现实的意义所在啊~!
Fu f = new Zi();
                         f.teach();//在这里打印输出的结果是"教java".然后我就郁闷了,
                         //不是说父类只能调用父类吗?这个编译就应该报错的啊?怎么会调用子类的方法呢?

此句中,具体teach()的方法,已经被Zi类覆写,而且此功能是由new Zi()新创建的子类的实际对象所提供的。f仅仅是引用而已,说白点就是个代号罢了。就像“毕姥爷”是代号,其实是由毕老师化妆而成的一样......教书的功能已经变成教java了。

评分

参与人数 2技术分 +1 黑马币 +8 收起 理由
黄奕豪 + 1 赞一个!
贾飞雨 + 8

查看全部评分

回复 使用道具 举报
Fu f = new Zi();这个是上转型对象,对象的上转型对象的实体是由子类负责创建的,只不过失掉了一些属性和功能而已,需要注意的是不可以将父类创建的对象的引用值赋值给子类声明的对象。
class A
{
        double n;
        int m;
        void f()
        {
                System.out.printf("子类继承方法f(),n=%f,m=%d\n",n,m);
        }
        void g()
        {
                System.out.printf("你好,n=%f,m=%d\n",n,m);
        }
}
class B extends A
{
        int n=12;
        void g()
        {
                System.out.printf("子类重写方法g(),n=%d,m=%d\n",n,m);
        }
        void cry()
        {
                System.out.printf("子类新增的方法,n=%d,m=%d\n",n,m);
        }
}
public class E
{
        public static void main(String args[])
        {
                A a;
                a=new B();//a是子类对象的上转型对象
                a.n=0.618;//操作子类隐藏的double类型成员n
                a.m=200;//操作子类继承的成员m,等价于“b.m=200;”
                a.f();//调用子类继承的方法,等价于"b.f();"
                a.g();//调用子类重写的方法,等价于"b.g();"
                B b=(B)a;//上转型对象强制转换成子类对象
                b.n=555;//操作子类新增的int类型成员n
                b.cry();//a.cry();是非法的,特别注意这一点
        }
}  

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
黄奕豪 + 1 赞一个!
贾飞雨 + 2

查看全部评分

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