微信扫一扫打赏支持

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

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);//是父类,答案是3
101 
102 
103 //        Zi z = new Zi();
104 //        System.out.println(z.num);//是子类,答案是4
105     }
106 }

 

三、内存储存分析

Fu f = new Zi();

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

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

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

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

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

 

posted @ 2017-06-03 05:57  范仁义  阅读(768)  评论(0编辑  收藏  举报