溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-04-02 13:39:50 來源:億速云 閱讀:190 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)”文章能幫助大家解決問題。

    一、繼承

    1、繼承的概念

    繼承機(jī)制:是面向?qū)ο蟪绦蛟O(shè)計(jì)是代碼可以復(fù)用的最重要手段,允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加新的功能,產(chǎn)生的新類,成為派生類/子類。繼承主要解決的問題是:共性的抽取,實(shí)現(xiàn)代碼的復(fù)用。

    Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)

    2、繼承的語法

    表示類與類的繼承關(guān)系,需要借助關(guān)鍵字extends,語法如下:

    修飾符  class  子類/派生類   extends  父類/基類/超類{

           //…………

    }

    • 子類會(huì)將父類的成員變量或者成員方法繼承到子類中

    • 子類繼承父類后,必須添加自己特有的成員,體現(xiàn)與基類的不同

    3、父類成員訪問

    (1)子類中訪問父類的成員變量
    • 不存在同名成員變量時(shí),正常訪問就行

    • 存在同名成員變量,使用(super.變量名)實(shí)現(xiàn)父類成員變量的訪問

    public class Base {
        int a;
        int b;
        int c;
    } 
    public class Derived extends Base{
        int a; // 與父類中成員a同名,且類型相同
        char b; // 與父類中成員b同名,但類型不同
        public void method(){
            a = 100; // 訪問父類繼承的a,還是子類自己新增的a?
            b = 101; // 訪問父類繼承的b,還是子類自己新增的b?
            c = 102; // 子類沒有c,訪問的肯定是從父類繼承下來的c
        }
    }
    • 訪問成員變量時(shí),優(yōu)先訪問自己的成員變量。即同名成員變量訪問時(shí),優(yōu)先訪問子類的。即:子類將父類的成員隱藏了

    • 成員變量訪問遵循就近原則,自己有優(yōu)先自己的,自己沒有則向父類中查找。

    (2)子類中訪問父類的成員方法
    • 成員方法名字不同,正常訪問即可

    • 成員方法名字相同,可以通過 【super.方法名】訪問同名父類方法

    如果父類和子類同名方法的參數(shù)列表不同(重載),根據(jù)調(diào)用方法時(shí)傳遞的參數(shù)選擇合適的方法訪問。

    如果父類和子類的同名方法原型一致,則訪問子類的

    4、super關(guān)鍵字

    super關(guān)鍵字的主要作用是:在子類方法中訪問父類的同名成員。(只能在非靜態(tài)方法中使用)

    public class Base {
        int a;
        int b;
        public void methodA(){
            System.out.println("Base中的methodA()");
        }
        public void methodB(){
            System.out.println("Base中的methodB()");
    }
    public class Derived extends Base{
        int a; 
        char b; 
        // 與父類中methodA()構(gòu)成重載
        public void methodA(int a) {
            System.out.println("Derived中的method()方法");
        }
        // 與父類中methodB()構(gòu)成重寫
        public void methodB(){
            System.out.println("Derived中的methodB()方法");
        }
        public void methodC(){
            a = 100; // 等價(jià)于: this.a = 100;
            b = 101; // 等價(jià)于: this.b = 101;
            // 訪問父類的成員變量時(shí),需要借助super關(guān)鍵字
            // super是獲取到子類對(duì)象中從基類繼承下來的部分
            super.a = 200;
            super.b = 201;
            methodA(); // 沒有傳參,訪問父類中的methodA()
            methodA(20); // 傳遞int參數(shù),訪問子類中的methodA(int)
            methodB(); // 直接訪問,則永遠(yuǎn)訪問到的都是子類中的methodA(),基類的無法訪問到
            super.methodB(); // 訪問基類的methodB()
        }
    }

    5、子類構(gòu)造方法

    子類對(duì)象構(gòu)造時(shí),需要先調(diào)用父類的構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法。

    public class Base {
        public Base(){
            System.out.println("Base()");
        }
    }
    public class Derived extends Base{
        public Derived(){
       // super(); // 注意子類構(gòu)造方法中默認(rèn)會(huì)調(diào)用基類的無參構(gòu)造方法:super(),
       // 用戶沒有寫時(shí),編譯器會(huì)自動(dòng)添加,而且super()必須是子類構(gòu)造方法中第一條語句,
       // 并且只能出現(xiàn)一次
            System.out.println("Derived()");
        }
    }
    • 若父類顯示定義無參或者默認(rèn)的構(gòu)造函數(shù),在子類的構(gòu)造方法第一行默認(rèn)有隱含的super()調(diào)用。

    • 父類定義帶參數(shù)的構(gòu)造方法時(shí),編譯器不會(huì)再給子類生成默認(rèn)的構(gòu)造方法,需要子類顯式定義,并在子類構(gòu)造方法中調(diào)用合適的父類構(gòu)造方法

    • 子類構(gòu)造方法中,super(……)調(diào)用父類構(gòu)造方法,必須是子類構(gòu)造方法的第一條語句

    • super(……)只能在子類構(gòu)造方法中出現(xiàn)一次,并且不能和this同時(shí)出現(xiàn)

    6、super和this

    super和this都可以在成員方法中用來訪問成員變量和調(diào)用其他的成員函數(shù),都可以作為構(gòu)造方法的第一條語句,那么它們之間的區(qū)別是什么?

    (1)相同點(diǎn)

    • 都是java的關(guān)鍵字

    • 只能在類的非靜態(tài)方法中使用,用來訪問非靜態(tài)成員方法和屬性

    • 必須作為構(gòu)造方法中的第一條語句,并且不能同時(shí)存在

    (2)不同點(diǎn)

    • this是當(dāng)前對(duì)象的引用,super是子類對(duì)象中從父類繼承的成員的引用

    • this是非靜態(tài)成員方法的一個(gè)隱藏參數(shù),super不是隱藏參數(shù)

    • 在構(gòu)造方法中:this()用于調(diào)用本類的構(gòu)造方法,super()用來調(diào)用父類構(gòu)造方法,兩種調(diào)用不能同時(shí)出現(xiàn)在構(gòu)造方法中

    • 子類的構(gòu)造方法中一定會(huì)存在super()的調(diào)用,但是this()用戶不寫就沒有

    7、代碼塊執(zhí)行順序

    【普通類】

    • 靜態(tài)代碼塊先執(zhí)行,并且只執(zhí)行一次,在類加載階段執(zhí)行

    • 當(dāng)有對(duì)象創(chuàng)建時(shí),才會(huì)執(zhí)行實(shí)例代碼塊,最后執(zhí)行構(gòu)造方法

    【繼承關(guān)系上的執(zhí)行順序】

    • 父類靜態(tài)代碼塊優(yōu)先于子類靜態(tài)代碼塊執(zhí)行,最早執(zhí)行

    • 父類實(shí)例代碼塊和父類構(gòu)造方法緊接著執(zhí)行

    • 子類的實(shí)例代碼塊和構(gòu)造方法最后執(zhí)行

    • 第二次實(shí)例化子類對(duì)象時(shí),父類和子類的靜態(tài)代碼塊不會(huì)再執(zhí)行

    8、繼承方式

    【注】Java中不支持多繼承

    Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)

    • super只能指代直接父類

    • 繼承關(guān)系一般不超過三層

    9、final關(guān)鍵字

    • 修飾變量時(shí),表示常量(不能修改)

    • 修飾類:此類不能被繼承

    • 修飾方法:表示方法不能被重寫

    10、繼承和組合

    組合和繼承都能實(shí)現(xiàn)代碼的復(fù)用。組合沒有涉及到特殊的語法(如extend關(guān)鍵字),僅僅是將一個(gè)類的實(shí)例作為另一個(gè)類的屬性。

    • 繼承表示對(duì)象與對(duì)象之間是is-a的關(guān)系

    • 組合表示對(duì)象與對(duì)象之間是has-a的關(guān)系

    一般建議:能用組合盡量用組合

    二、多態(tài)

    1、向上轉(zhuǎn)型

    通過父類類型的引用調(diào)用子類對(duì)象,向上轉(zhuǎn)型是安全的

    【發(fā)生向上轉(zhuǎn)型的時(shí)機(jī)】

    • 直接賦值

    • 方法傳參

    • 函數(shù)的返回值

    public class TestAnimal {
        // 2. 函數(shù)傳參:形參為父類引用,可以接收任意子類的對(duì)象
        public static void eatFood(Animal a) {
            a.eat();
        }
     
        // 3. 作返回值:返回任意子類對(duì)象
        public static Animal buyAnimal(String var) {
            if ("狗" == var) {
                return new Dog("狗狗", 1);
            } else if ("貓" == var) {
                return new Cat("貓貓", 1);
            } else {
                return null;
            }
        }
     
        public static void main(String[] args) {
            Animal cat = new Cat("元寶", 2); // 1. 直接賦值:子類對(duì)象賦值給父類對(duì)象
            Dog dog = new Dog("小七", 1);
        }
    }

    優(yōu)缺點(diǎn):

    • 優(yōu)點(diǎn):讓代碼更加靈活

    • 缺點(diǎn):不能訪問到子類特有的方法

    2、重寫

    函數(shù)名相同、參數(shù)列表相同、返回值相同或是【協(xié)變類型】(父子類關(guān)系)

    【方法重寫的規(guī)則】

    • 重寫的方法訪問權(quán)限不能比父類中原方法的的權(quán)限低;

    • 父類中被static、private、final修飾的方法、構(gòu)造方法不能被重寫;

    • 重寫的方法,可以使用 @override 注解來顯示指定(幫助我們進(jìn)行一些合法性的檢驗(yàn))。比如方法名拼寫錯(cuò)誤,編譯會(huì)報(bào)錯(cuò);

    • 重寫的返回值類型可以不同,但是必須具有父子關(guān)系。

    • 被final修飾的方法,叫做密封方法,該方法不能被重寫。

    • 外部類只能是public或者默認(rèn)權(quán)限

    【動(dòng)態(tài)綁定和靜態(tài)綁定】

    • 動(dòng)態(tài)綁定:發(fā)生的條件(1、父類引用引用子類對(duì)象;2、通過父類引用,可以訪問到子類中的方法)。后期綁定,即在編譯時(shí)不能確定方法的行為,需要等到程序運(yùn)行時(shí),才能夠確定調(diào)用哪個(gè)類的方法;

    • 靜態(tài)綁定:前期綁定,編譯時(shí),根據(jù)用戶傳遞的參數(shù)類型確定具體的調(diào)用方法(函數(shù)重載)

    3、多態(tài)

    一個(gè)引用調(diào)用同一個(gè)方法,可以表現(xiàn)出不同的形式,這種思想稱為多態(tài)。在父類的構(gòu)造方法中不要調(diào)用重寫的方法。

    【多態(tài)實(shí)現(xiàn)的條件】

    • 必須在繼承條件下

    • 子類對(duì)父類方法進(jìn)行重寫

    • 通過父類引用調(diào)用重寫的方法

    • 發(fā)生了向上轉(zhuǎn)型

    public class Animal(){
        String name;
        int age;
        public Animal(String name, int age){
            this.name = name;
            this.age = age;
        }
        public void eat(){
            System.out.println(name + "吃飯");
            }
    }
    public class Cat extends Animal{
        public Cat(String name, int age){
            super(name, age);
        }
        @Override
        public void eat(){
            System.out.println(name+"吃魚~~~");
        }
    }
    public class Dog extends Animal {
        public Dog(String name, int age){
            super(name, age);
        }
        @Override
        public void eat(){
            System.out.println(name+"吃骨頭~~~");
        }
    }
    public class TestAnimal {
        // 編譯器在編譯代碼時(shí),并不知道要調(diào)用Dog 還是 Cat 中eat的方法
       // 等程序運(yùn)行起來后,形參a引用的具體對(duì)象確定后,才知道調(diào)用那個(gè)方法
       // 注意:此處的形參類型必須時(shí)父類類型才可以
        public static void eat(Animal a){
            a.eat();
        }
        public static void main(String[] args) {
            Animal animal1 = new Cat("元寶",2);
            Animal animal2 = new Dog("小七", 1);
            eat(animal1);
            eat(animal2);
        }
    }

    【注】Java中所有的類默認(rèn)繼承Object類

    關(guān)于“Java繼承與多態(tài)的概念是什么及怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI