• 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、如果用父类引用指向这个对象,全部访问的是这个对象里面父类的,只不过父类函数被覆盖,所以导致成员是父类,函数时子类的。

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

  • 相关阅读:
    质数检测器
    《视觉SLAM十四讲》学习日志(一)——预备知识
    C++类的介绍
    Python数据类型解析(基础篇)
    括号匹配详解
    哈夫曼树编码
    分治之归并,快速排序
    洛谷p2216 多次单调队列,扫描矩阵中的最大值减去最小值最的固定大小子矩阵
    洛谷p1886滑动窗口最大最小值 双单调队列
    洛谷p1725 露琪诺 单调队列优化的DP
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/6936090.html
Copyright © 2020-2023  润新知