网站推广.NET

网站推广.NET

多态是什么?多态的特点

来源:互联网

java基础十二--多态是成员的特点

一、特点

1,成员变量。

编译和运行都参考等号的左边。

覆盖只发生在函数上,和变量没关系。

Fu f = new Zi();
System.out.println(f.num);//是父类,答案是3

2,成员函数(非静态)。

编译看左边,运行看右边。

因为成员函数存在覆盖特性。

Fu f = new Zi();//
f.show();
输出的是子类里面的show方法

3,静态函数。

编译和运行都看左边。

静态函数不具备多态性,多态性是对象的多态性,然后静态函数不涉及对象。

Fu f = new Zi();//
f.show();
这里最后输出的是父类的show里面的内容。

Zi z = new Zi();//
z.show();

输出的是子类里面的show

 

二、实例

  1 /*  2 多态时,  3 成员的特点:  4 1,成员变量。  5     编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。  6     运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。  7     简单说:编译和运行都参考等号的左边。哦了。  8     作为了解。  9 覆盖只发生在函数上,和变量没关系。 10 Fu f = new Zi(); 11 System.out.println(f.num);//是父类,答案是3 12 没根据f的值(子类对象的地址)去找,而是根据f的类型去找。 13 开发时不可能出现这样的情况,我父类有了,我子类就直接拿来用了,而且用的时候一般都已经向下转型了。 14  15  16  17  18 2,成员函数(非静态)。 19     编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。 20     运行时:参考的是对象所属的类中是否有调用的函数。 21     简单说:编译看左边,运行看右边。 22  23     因为成员函数存在覆盖特性。 24 Fu f = new Zi();// 25 f.show(); 26 输出的是子类里面的show方法 27 依赖的是对象,有对象才有成员函数,必须动态的绑定到指定的对象上,所以运行的时候是看子类,而编译的时候检查语 28  29 法错误,所以编译的时候检查父类,所以看父类。 30 编译检查语法错误,运行时根据引用指向的地址运行。 31  32  33  34  35 3,静态函数。 36         编译时:参考引用型变量所属的类中的是否有调用的静态方法。 37         运行时:参考引用型变量所属的类中的是否有调用的静态方法。 38         简单说,编译和运行都看左边。 39  40         其实对于静态方法,是不需要对象的。直接用类名调用即可。 41 Fu f = new Zi();// 42 f.show(); 43 这里最后输出的是父类的show里面的内容,因为静态成员不需要对象,直接是被类名指向,都指向存静态方法的方法区, 44  45 而那个里面存的就是父类的show。 46 Zi z = new Zi();// 47 z.show(); 48 这里的zi是继承fu的,show方法是静态的 49 输出的是子类里面的show 50 其实可以理解为静态函数不具备多态性,多态性是对象的多态性,然后静态函数不涉及对象 51 父类对象引用,就是指向父类的静态函数 52 子类对象引用,就是指向子类的对象函数 53  54  55          56  57 */ 58  59 class Fu 60 { 61 //    int num = 3; 62     void show() 63     { 64         System.out.println("fu show"); 65     } 66  67     static void method() 68     { 69         System.out.println("fu static method"); 70     } 71 } 72  73 class Zi extends Fu 74 { 75 //    int num = 4; 76     void show() 77     { 78         System.out.println("zi show"); 79     } 80  81     static void method() 82     { 83         System.out.println("zi static method"); 84     } 85 } 86  87  88  89 class  DuoTaiDemo3 90 { 91     public static void main(String[] args)  92     { 93         Fu.method(); 94         Zi.method(); 95 //这个的实质是父类对象指向子类引用,就是有点像指针,f的值是子类对象的地址。 96         Fu f = new Zi();// 97 //        f.method();//输出是父类的静态 98 //        f.show();//编译的时候检查的是父类,运行的时候以子类为主,show被覆盖,运行的子类的show 99         //输出是子类的show,100 //        System.out.println(f.num);//是父类,答案是3101 102 103 //        Zi z = new Zi();104 //        System.out.println(z.num);//是子类,答案是4105     }106 }

 

三、内存储存分析

Fu f = new Zi();

Fu f 在栈中定义了一个引用,也就是指针。

new Zi() 在堆中定义了一个对象,只不过这个对象有父类的那一部分成员。

1、如果用子类引用指向这个对象,全部访问的是子类的。

2、如果用父类引用指向这个对象,全部访问的是这个对象里面父类的,只不过父类函数被覆盖,所以导致成员是父类,函数时子类的。

肯定是根据指针类型去访问要访问的东西。猫肯定要去吃猫粮,狗才去吃狗粮。

多态是什么