黑马程序员技术交流社区

标题: 关于多态执行的小问题 [打印本页]

作者: 安浦鑫    时间: 2012-5-27 15:11
标题: 关于多态执行的小问题
                Fu f = new Zi();
                A:成员变量:编译和运行都看Fu。
                B:非静态方法:编译看Fu,运行看Zi。
                C:静态方法:编译和运行都看Fu。
我现在知道这3条规则,但是关于这三条规则为何这样实现不了解,想知道在这三种情况下内存中都发生了什么
作者: 李红飞    时间: 2012-5-27 15:58

1:
                class Fu
                {
                 int num = 5;       
                }

                class Zi extends Fu
                {
                 int num = 8;       
                }
                class  DuoTaiDemo4
                {
                        public static void main(String[] args)
                        {
                               
                        Fu f = new Zi();      运行后,子类对象由两个 变量(一个继承,一个自定义),当父类引用调用时,先找从父类继承的变量
                        System.out.println(f.num);           5
                        Zi z = new Zi();
                        System.out.println(z.num);                8       
                        }
                }
                在多态中,成员变量的特点:
                无论编译和运行,都参考左边(引用型变量所属的类)。
内存状况:    因为在子类栈内存中有俩个同名的变量当父类引用调用时,先找从父类继承的变量
2:
class Fu
{
        static void method4()
        {
                System.out.println("fu method_4");
        }
}
class Zi extends Fu
{
        static void method4()
        {
                System.out.println("zi method_4");
        }
}
class  DuoTaiDemo4
{
        public static void main(String[] args)
        {
                Fu f = new Zi();
                f.method4();      //fu method_4
                Zi z = new Zi();
                z.method4();       //zi method_4
        }
}

(因为静态方法没有覆盖功能,静态方法不属于对象,属于类型 这里属于绑定概念,静态方法静态绑定在其所属类上(即左边) 属于编译时干的事)
而      Fu f = new Zi();
                f.method1();属于动态绑定在其所属对象(new Zi())(即右边)(属于运行时干的事)上
在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。






作者: 龚正军    时间: 2012-5-27 16:21
标题: (tuan
本帖最后由 龚正军 于 2012-5-27 18:40 编辑

你上面说的是:毕老师是对于不同情况(特殊情况)下的多态不同表现的总结。
但我个人感觉如果已经懂的人看总结是有用的,但是如果没有懂的人去看反而会出问题。所以我的建议是楼主要理解多态的真正含义和在静态时候等特殊情况下到底发生什么,先别管毕老师的总结为好!

我个人根据我所知道尽力给你解释下你提问的3点:

前两个问题是一个问题:A:成员变量:编译和运行都看Fu和 B:非静态方法:编译看Fu,运行看Zi------------------------------首先你要理解多态的含义:(如果要讲多态的话估计一两天都能丢进去,多态的应用太广,太大,在这不扩展,楼主可以查看下)我在这讲我的理解:多态必须依靠继承关系,并且在“通用”情况下是由于有函数复写机制造成的。
好了,明白上面2点后,我们在来分析Fu f = new Zi();----------我们首先了解变量F到底是什么,我们把这句子分2段:Fu f;这是声明一个变量f为Fu这个类,那么我们知道了f肯定是Fu类。然后我们f=new Zi();中建立一个子类对象赋值给了f,结果是什么难??
结果是,拥有了被Zi类函数覆盖后的Fu类对象----f------。

-------------------------------------------也就是说:只有子类的函数覆盖了父类的函数这一个变化,但是f肯定是Fu这个类,也就是说f不可能变成其他比如Zi这个类等等(突然f拥有了Zi类特有函数,成员变量等都是不可能的)。所以f所代表的是函数被复写后(多态的意义)的一个Fu类,而Fu类原来有的成员变量(不是成员函数不可能被复写)没有任何变化----------------获得结论:A:成员变量:编译和运行都看Fu。
-------------------------------------------但是f的Fu类函数被复写了。--------------获得结论:B:非静态方法:编译看Fu,运行看Zi

----------------------------------------------------------------------------------------割掉-------------------------------------------------------------------------------------------

第三个问题在静态情况下:(特殊情况)C:静态方法:编译和运行都看Fu!!
其实很简单,首先我们要理解静态情况下发生了什么?----------------当静态时,Fu类的所有函数跟随Fu类加载而加载了。也就是Fu类的函数(是先于对象建立之前就存在了,无法被后出现的Zi类对象所复写的,所以没发生复写,那么获得:C:静态方法:编译和运行都看Fu。

作者: 徐炯    时间: 2012-5-27 18:25
龚正军 发表于 2012-5-27 16:21
你上面说的是:毕老师是对于不同情况(特殊情况)下的多态不同表现的总结。
但我个人感觉如果已经懂的人看 ...

回答的真好,赞一个!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2