Java 第七天(純乾貨)(帶你14天瞭解並掌握Java SE)

 

今日內容

  • 繼承
  • super關鍵字以及方法重寫
  • 多態

01. 繼承的概述

  • 什麼是繼承?
  • 如何實現繼承關係?
  • 什麼時候用繼承?
總結:
    1. 繼承就是讓類與類之間產生關係,子父類關係,子類就可以直接使用父類中【非私有的成員】

    2. extends

        class 子類 extends 父類 {

        }

    3. 當事物之間產生了一種is..a的關係,誰是誰的一種

            老師類,學生類     -> Person類

            蘋果類,香蕉類     -> 水果類

            狗類,貓類           -> 動物類


    稱呼:

            父類:超類,基類
            子類:派生類

案例演示: 貓,狗,動物類.(不加private)
5分鐘時間練習

02. 繼承的好處和弊端

  • 繼承的好處是什麼?
  • 繼承的弊端是什麼?
總結:
    1.
        A. 提高了代碼的複用性
        B. 提高了代碼的維護性


        C. 是多態的前提
    2.
        類的耦合性增強了.
            開發將就: 高內聚, 低耦合.

            耦合: 類與類之間的關係太過緊密
            內聚: 自己完成事情的能力.

                A類的修改,不要影響到B類

案例演示: 貓,狗,動物類, 屬性加入private

03. Java中繼承的特點

  • 思考問題: 一個類是否可以擁有兩個爹?
  • 繼承的特點
總結:
    1: Java只支持單繼承,不支持多繼承,但是允許多層繼承。

問題:
    憑啥不支持多繼承?

        假如允許多繼承,多個父類中有相同的方法聲明,但方法的功能主體都不一樣,這時候編譯器無法判斷該執行哪一段功能主體,所以不允許!


例子:

    class A {
        public void method(){
            System.out.println("A....");
        }
    }

    class B {
        public void method(){
            System.out.println("B....");
        }
    }

    class C extends A, B{

    }

    C c = new C();
    c.method();     // 打印A...還是B... ? 懵了!


多層繼承的例子:

    class A {
        public void method(){
            System.out.println("A");
        }
    }

    class B extends A {
        public void show(){
            System.out.println("B");
        }
    }

    class C extends B {

    }

    C c = new C();

    c.method();
    c.show();

04. Java繼承中成員變量的特點

  • 如果子父類中出現了相同的成員變量, 那麼創建子類對象的時候, 用的是誰的成員變量?
  • 繼承中成員變量的特點
總結:
    1. 子類的成員變量

        問題:爲什麼會使用子類的?

                    此處採用的是就近原則。 

05. super關鍵字的概述和使用

  • super關鍵字代表什麼?
  • this和super的區別又是什麼?
總結:
    1. super的作用:用來調用父類中相關的成員【成員變量,成員方法】

            this : 代表當前對象的引用,誰來調用我,我就代表誰 (代表子類對象的引用)

            super : 代表父類對象的引用

    2.
        調用成員分類:

            1. 成員變量

                    this : 調用本類的成員變量

                            class A {
                                int num = 10;
                            }

                            class B extends A {

                                // this也可以調用父類成員,但是存在前提:子類中沒有定義跟父類相同的成員變量

                                public void show(){
                                    System.out.println(this.num);   // 10
                                }
                            }

                    super : 調用父類的成員變量

            2. 成員方法

                    this :  調用本類成員方法

                    super : 調用父類成員方法



    class Dad {
        String name = "建霖";
    }

    class Kid extends Dad {
        String name = "四蔥";

        public void show() {
            String name = "五蔥";
            System.out.println(name);   //五蔥
            System.out.println(this.name);  //四蔥
            System.out.println(super.name); //建霖
        }
    }

06. Java繼承中構造方法的特點

  • 需要搞清楚的是子父類誰先完成初始化的問題
總結: 
      一定是父類先完成初始化
            爲什麼?

                因爲子類在創建對象並使用的時候,有可能會使用到父類的成員,如果父類沒有完成初始化,子類就訪問不到了

                class Fu{
                    int num = 10;
                }

                class Zi extends Fu{

                    public Zi(){
                        super();
                        System.out.println(num);
                    }
                }


    重點: 
        子類的每一個構造方法中都默認含有super()這個語句, 目的就是爲了訪問父類的空參構造!!!

                意義:爲了完成父類的初始化.


問題: 如果父類沒有空參構造子類怎麼辦?

            如果父類沒有空參構造,那絕對存在有參構造

                解決方案:

                        通過super訪問父類的有參構造


            結論:子類無論如何,都需要有一個渠道去訪問父類的構造方法
                    super();  super(10);


            建議:今後無論是父類還是子類,空參有參構造都手動給出


注意:
        super() : 調用父類構造方法
        this() : 調用本類構造方法

            兩條語句必須寫在構造方法的第一行有效語句,而且兩者都在爭奪第一行的位置,所以二者衝突

07. Java繼承中成員方法的特點

  • 子父類中如果出現了相同的方法, 那麼調用的時候將會採用???
  • 成員方法訪問特點:
總結: 
    1. 子父類中,如果出現了重名的成員方法,在創建子類對象調用方法的時候,使用的是子類的成員方法

    2. 如果子父類中沒有出現相同的方法, 那麼在調用的時候, 會看子類有沒有這個方法.
            沒有的話, 就調用父類的方法

08. 方法重寫的概述和使用(重點!!!)

  • 什麼是方法的重寫?
  • 什麼情況下需要使用重寫?
方法的重載(Overload):在同一個類中,方法名相同,參數列表不同,與返回值無關。

總結:
    1. 方法的重寫(Override): 在子父類當中,出現了方法聲明一模一樣(方法名相同,參數列表也相同)的方法

    2. 當子類需要父類的功能,子類方法的功能主體,又有自己特有的實現方式,這時候就可以對父類的方法進行重寫

            這樣做即沿襲了父類的功能,又定義了子類特有的內容


            大白話: 子類覺得父類的方法不好,或者說是過於老舊,就可以對父類的方法進行重寫。


    @Override : 檢測當前的方法,是否是重寫的方法

舉例: 手機的列子.

09. 方法重寫的注意事項

  • 重寫有哪些注意事項?
總結:
    1. 子類不能重寫父類中私有的方法


    2. 子類重寫父類方法的時候,訪問權限,必須大於等於父類,最好就一致

            private  
            default
            protected
            public 


                問題:爲什麼訪問權限一定要大於等於父類呢?
                        子類重寫父類方法,就是爲了將功能變得更加強大,所以權限需要越來越大.

10. 繼承的練習(學生和老師案例)

  •  
  學生類:
        成員變量:name,age
        構造方法:無參,帶參
        成員方法:getXxx(),setXxx(),study()
  老師類:
        成員變量:name,age
        構造方法:無參,帶參
        成員方法:getXxx(),setXxx(),teach()
  我們發現這兩個類中相同的代碼比較多,所以提取出一個父類。
  人類:
        成員變量:name,age
        構造方法getXxx(),setXxx()
  學生類:
        繼承人類
        study()
  老師類:
        繼承人類
        teach()
  •  
 必須敲明白的代碼:

    需求:

        程序員類:Coder
                姓名 工號 工資
                工作
        項目經理類:Manager
                姓名 工號 工資  獎金
                工作.

        要求抽取出父類, 私有成員變量, 提供setXxx  getXxx方法.
        在編寫項目經理類的時候, 通過父類初始化3個共有的變量, 特有的變量自己完成初始化!!!

11. 多態的概述和代碼體現

  • 什麼是多態?
  • 多態的前提是什麼?
總結:
    1. 事物存在的多種形態

            Dog d = new Dog();  // 事物是一隻狗
            Aniaml a = new Dog();  // 事物是一隻動物

    2.
        A. 要有繼承關係
        B. 要有父類引用指向子類對象

12. 多態中的成員訪問特點

  • 多態調用成員變量
  • 多態調用成員方法
  • 多態調用靜態方法
總結:
    1. 編譯看左邊(父類),運行看左邊(父類)
            Fu f = new Zi();
            System.out.println(f.num);      // num執行的是父類的10
            原因: 因爲是多態創建對象,持有的是父類的引用,父類的引用有限制,只能看到堆內存中,super的一小塊區域

    2. 編譯看左邊(父類),運行看右邊(子類)
            原因:在多態創建對象調用成員方法的時候,編譯看父類中是否有此方法

                沒有:編譯失敗
                有:編譯通過,但是運行的時候,執行子類的邏輯(動態綁定機制)

13. 多態的好處和弊端

總結:
    好處:
            因爲多態有繼承保證:
                    1. 提高了代碼的複用性
                    2. 提高了代碼的維護性
                    -----------------

                    1. 提高了代碼的擴展性!!!

                        可以將一個方法的形參定義爲父類類型,該方法就可以接受這個父類的任意子類對象。

                        public class Demo1_DuoTai {
                            public static void main(String[] args) {
                                useAnimal(new Dog());
                                useAnimal(new Cat());
                            }

                            /*
                             * 可以將方法的形參,定義爲父類類型,該方法就可以接受這個類的,任意子類對象
                             */
                            public static void useAnimal(Animal a){ // Animal a = new Animal();
                                                                    // Animal a = new Dog();
                                                                    // Animla a = new Cat();
                                a.eat();
                            }

                        }

    弊端:

            不能調用子類特有的屬性和行爲。

                非要調用的話,就需要向下轉型!


                原因:因爲多態創建對象,編譯時都會看父類中有沒有,而子類特有的屬性和行爲,在父類中都不存在。
                        報錯!

14. 多態中的轉型問題

  • 基本數據類型轉換回顧
  • 引用數據類型轉換
總結:
    1.

        隱式轉換:
            概念: 將小的數據類型直接賦值給大的數據類型

            double d = 10;

            Animal a = new Dog();   // 向上轉型 

        強制類型轉換:

            概念: 將大的數據類型賦值給小的數據類型

            double d = 12.3;
            int i = (int)d;     


    2.
            Person p = new SuperMan();  // 向上轉型
            SuperMan sm = (SuperMan)p;  // 向下轉型.

注意:  向下轉型的強轉, 必須發生在子父類的關係當中, 而且必須先轉上去, 才能轉下來.

        ClassCastException : 類型轉換異常, 願意: 出現了錯誤的強轉.

            錯誤1: Person p = new Person();       SuperMan sm = (SuperMan)p;
            錯誤2: Animal a = new Dog();          Cat c = (Cat)a;

15. 多態轉型問題內存圖解

  • 看圖說話

16. 多態的練習

  • 創建一個“動物類”,包含吃的方法
  • 創建一個“貓類”,包含吃的方法和玩的方法
  • 創建一個“狗類”,包含吃的方法和玩的方法
關鍵字: instanceOf

        判斷左邊的引用, 是否是右邊的數據類型

    public static void method(Animal a){    // Animal a  = new Dog();
                                            // Animal a  = new Cat();
        // 調用共有的行爲
        a.eat();
        // 向下轉型, 調用特有的行爲
        if(a instanceof Dog){               // instanceof : 判斷左邊的引用是否是右邊的數據類型.
            Dog d = (Dog) a;
            d.playGame();
        }else if(a instanceof Cat){
            Cat c = (Cat) a;
            c.playGame();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章