国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【JAVASE】帶你了解面向對象三大特性之一(多態(tài))

這篇具有很好參考價值的文章主要介紹了【JAVASE】帶你了解面向對象三大特性之一(多態(tài))。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

?作者簡介:大家好,我是橘橙黃又青,一個想要與大家共同進步的男人????

??個人主頁:再無B~U~G-CSDN博客

1.多態(tài)

1.1 多態(tài)的概念

多態(tài)的概念:通俗來說,就是多種形態(tài), 具體點就是去完成某個行為,當不同的對象去完成時會產生出不同 的狀 態(tài)。
【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言
【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言
總的來說:同一件事情,發(fā)生在不同對象身上,就會產生不同的結果。

1.2 多態(tài)實現(xiàn)條件

java 中要實現(xiàn)多態(tài),必須要滿足如下幾個條件,缺一不可:
1. 必須在繼承體系下
2. 子類必須要對父類中方法進行重寫
3. 通過父類的引用調用重寫的方法

?多態(tài)體現(xià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 {
    // 編譯器在編譯代碼時,并不知道要調用Dog 還是 Cat 中eat的方法
    // 等程序運行起來后,形參a引用的具體對象確定后,才知道調用那個方法
    // 注意:此處的形參類型必須時父類類型才可以
    public static void eat(Animal a){
        a.eat();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("元寶",2);
        Dog dog = new Dog("小七", 1);
        eat(cat);
        eat(dog);
    }
}

輸出結果:

元寶吃魚 ~~~
元寶正在睡覺
小七吃骨頭 ~~~
小七正在睡覺
在上述代碼中 , 分割線上方的代碼是 類的實現(xiàn)者 編寫的 , 分割線下方的代碼是 類的調用者 編寫的 .
當類的調用者在編寫 eat 這個方法的時候 , 參數類型為 Animal ( 父類 ), 此時在該方法內部并 不知道 , 也不關注 當前的 a 引用指向的是哪個類型 ( 哪個子類 ) 的實例 . 此時 a 這個引用調用 eat 方法可能會有多種不同的表現(xiàn) ( a 引用的實例 相關), 這種行為就稱為 多態(tài) .

?【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

1.3 重寫

重寫 (override) :也稱為覆蓋。 重寫是子類對父類非靜態(tài)、非private修飾,非final修飾,非構造方法等的實現(xiàn)過程 進行重新編寫 , 返回值和形參都不能改變 即外殼不變,核心重寫! 重寫的好處在于子類可以根據需要,定義特定于自己的行為。 也就是說子類能夠根據需要實現(xiàn)父類的方法。

方法重寫的規(guī)則?

  • 訪問權限不能比父類中被重寫的方法的訪問權限更低。例如:如果父類方法被public修飾,則子類中重寫該方法就不能聲明為 protected
  • 子類在重寫父類的方法時,一般必須與父類方法原型一致: 返回值類型 方法名 (參數列表) 要完全一致
  • 被重寫的方法返回值類型可以不同,但是必須是具有父子關系的.
  • 父類被static、private修飾的方法、構造方法都不能被重寫。
  • 重寫的方法, 可以使用 @Override 注解來顯式指定. 有了這個注解能幫我們進行一些合法性校驗. 例如不小心將方法名字拼寫錯了 (比如寫成 aet), 那么此時編譯器就會發(fā)現(xiàn)父類中沒有 aet 方法, 就會編譯報錯, 提示無法構成重寫.

?重寫和重載的區(qū)別

區(qū)別點
重寫 (override)
重載 (override)
參數列表
一定不能修改
必須修改
返回類型
一定不能修改【除非可以構成父子類關系】
可以修改
訪問限定符
一定不能做更嚴格的限制(可以降低限制)
可以修改

【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

重寫的設計原則
對于已經投入使用的類,盡量不要進行修改。最好的方式是:重新定義一個新的類,來重復利用其中共性的內容, 并且添加或者改動新的內容。
例如:若干年前的手機,只能打電話,發(fā)短信,來電顯示只能顯示號碼,而今天的手機在來電顯示的時候,不僅僅可以顯示號碼,還可以顯示頭像,地區(qū)等。在這個過程當中,我們不應該在原來老的類上進行修改,因為原來的 類,可能還在有用戶使用 ,正確做法是: 新建一個新手機的類,對來電顯示這個方法重寫就好了,這樣就達到了我 們當今的需求了 。

?【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

靜態(tài)綁定 :也稱為前期綁定 ( 早綁定 ) ,即在編譯時,根據用戶所傳遞實參類型就確定了具體調用那個方法。典型代表函數重載。
動態(tài)綁定 :也稱為后期綁定 ( 晚綁定 ) ,即在編譯時,不能確定方法的行為,需要等到程序運行時,才能夠確定具體調用那個類的方法。

1.4 向上轉移和向下轉型

2.4.1 向上轉型

?向上轉型:實際就是創(chuàng)建一個子類對象,將其當成父類對象來使用。

語法格式:父類類型 對象名 = new 子類類型()

比如:

Animal animal = new Cat("元寶",2); ?

animal是父類類型,但可以引用一個子類對象,因為是從小范圍向大范圍的轉換。 ?

【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

使用場景
1. 直接賦值
2. 方法傳參
3. 方法返回
public class TestAnimal {
    // 2. 方法傳參:形參為父類型引用,可以接收任意子類的對象
    public static void eatFood(Animal a){
        a.eat();
    }
    // 3. 作返回值:返回任意子類對象
    public static Animal buyAnimal(String var){
        if("狗".equals(var) ){
            return new Dog("狗狗",1);
        }else if("貓" .equals(var)){
            return new Cat("貓貓", 1);
        }else{
            return null;
        }
    }
    public static void main(String[] args) {
        Animal cat = new Cat("元寶",2); // 1. 直接賦值:子類對象賦值給父類對象
        Dog dog = new Dog("小七", 1);
        eatFood(cat);
        eatFood(dog);
        Animal animal = buyAnimal("狗");
        animal.eat();
        animal = buyAnimal("貓");
        animal.eat();
    }
}
向上轉型的優(yōu)點:讓代碼實現(xiàn)更簡單靈活。
向上轉型的缺陷:不能調用到子類特有的方法。

2.4.2 向下轉型

將一個子類對象經過向上轉型之后當成父類方法使用,再無法調用子類的方法,但有時候可能需要調用子類特有的 方法,此時:將父類引用再還原為子類對象即可,即向下轉換。
【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言
接上面代碼
package com.cdm.test;

class Animal {
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println(this.name +" 正在吃!");
    }
}
class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);//alt +回車
    }
    public void bark() {
        System.out.println(this.name + " 旺旺叫!");
    }
    @Override
    public void eat() {
        System.out.println(this.name +" 正在吃狗糧!");
    }

}
class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);//alt +回車
    }
    public void bark() {
        System.out.println(this.name + " 喵喵叫!");
    }
    @Override
    public void eat() {
        System.out.println(this.name +" 正在貓狗糧!");
    }

}
package com.cdm.test;

public class TestAnimal {
    public static void main(String[] args) {
        Cat cat = new Cat("元寶",2);
        Dog dog = new Dog("小七", 1);
        // 向上轉型
        Animal animal = cat;
        animal.eat();
        animal = dog;
        animal.eat();

        // animal.bark();
        // 編譯失敗,編譯時編譯器將animal當成Animal對象處理
        // 而Animal類中沒有bark方法,因此編譯失敗

        // 向上轉型
        // 程序可以通過編程,但運行時拋出異常---因為:animal實際指向的是狗
        // 現(xiàn)在要強制還原為貓,無法正常還原,運行時拋出:ClassCastException
        cat = (Cat)animal;
        cat.bark();
        // animal本來指向的就是狗,因此將animal還原為狗也是安全的
        dog = (Dog)animal;
        dog.bark();
    }
}

報錯信息:【JAVASE】帶你了解面向對象三大特性之一(多態(tài)),JAVASE,java,開發(fā)語言

向下轉型用的比較少,而且不安全,萬一轉換失敗,運行時就會拋異常。 Java 中為了提高向下轉型的安全性,引入了 instanceof ,如果該表達式為 true ,則可以安全轉換。
public class TestAnimal {
    public static void main(String[] args) {
        Cat cat = new Cat("元寶",2);
        Dog dog = new Dog("小七", 1);
        // 向上轉型
        Animal animal = cat;
        animal.eat();
        animal = dog;
        animal.eat();
        if(animal instanceof Cat){
            cat = (Cat)animal;
            cat.mew();
        }
        if(animal instanceof Dog){
            dog = (Dog)animal;
            dog.bark();
        }
    }
}

關于instanceof和equals我們后面會講到。

2.5 多態(tài)的優(yōu)缺點

假設有如下代碼:

class Shape {
    //屬性....
    public void draw() {
        System.out.println("畫圖形!");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("?");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("●");
    }
}
class Flower extends Shape{
    @Override
    public void draw() {
        System.out.println("?");
    }
}
使用多態(tài)的好處
1. 能夠降低代碼的 " 圈復雜度 ", 避免使用大量的 if - else
什么叫 "圈復雜度" ?
  1. 圈復雜度是一種描述一段代碼復雜程度的方式. 一段代碼如果平鋪直敘, 那么就比較簡單容易理解. 而如果有很多的條件分支或者循環(huán)語句, 就認為理解起來更復雜.
  2. 因此我們可以簡單粗暴的計算一段代碼中條件語句和循環(huán)語句出現(xiàn)的個數, 這個個數就稱為 "圈復雜度". 如果一個方法的圈復雜度太高, 就需要考慮重構.
  3. 不同公司對于代碼的圈復雜度的規(guī)范不一樣. 一般不會超過 10

例如我們現(xiàn)在需要打印的不是一個形狀了, 而是多個形狀. 如果不基于多態(tài), 實現(xiàn)代碼如下: ?

public static void drawShapes() {
    Rect rect = new Rect();
    Cycle cycle = new Cycle();
    Flower flower = new Flower();
    String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
    for (String shape : shapes) {
        if (shape.equals("cycle")) {
            cycle.draw();
        } else if (shape.equals("rect")) {
            rect.draw();
        } else if (shape.equals("flower")) {
            flower.draw();
        }
    }
}
如果使用使用多態(tài) , 則不必寫這么多的 if - else 分支語句 , 代碼更簡單 .
public static void drawShapes() {
    // 我們創(chuàng)建了一個 Shape 對象的數組.
    Shape[] shapes = {new Cycle(), new Rect(), new Cycle(),
    new Rect(), new Flower()};
    for (Shape shape : shapes) {
        shape.draw();
    }
}
2. 可擴展能力更強
如果要新增一種新的形狀 , 使用多態(tài)的方式代碼改動成本也比較低 .
class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("△");
    }
}
對于類的調用者來說 (drawShapes 方法 ), 只要創(chuàng)建一個新類的實例就可以了 , 改動成本很低 .
而對于不用多態(tài)的情況 , 就要把 drawShapes 中的 if - else 進行一定的修改 , 改動成本更高 .
多態(tài)缺陷:代碼的運行效率降低
1. 屬性沒有多態(tài)性
????????當父類和子類都有同名屬性的時候,通過父類引用,只能引用父類自己的成員屬性
2. 構造方法沒有多態(tài)性

2.6 避免在構造方法中調用重寫的方法 ?

一段有坑的代碼 . 我們創(chuàng)建兩個類 , B 是父類 , D 是子類 . D 中重寫 func 方法 . 并且在 B 的構造方法中調用 func
class B {
    public B() {
        // do nothing
        func();
    }
    public void func() {
        System.out.println("B.func()");
    }
}
class D extends B {
    private int num = 1;
    @Override
    public void func() {
        System.out.println("D.func() " + num);
    }
}
public class Test {
    public static void main(String[] args) {
        D d = new D();
    }
}
// 執(zhí)行結果
D . func () 0

原因:文章來源地址http://www.zghlxwxcb.cn/news/detail-851489.html

  1. 構造 D 對象的同時, 會調用 B 的構造方法.
  2. B 的構造方法中調用了 func 方法, 此時會觸發(fā)動態(tài)綁定, 會調用到 D 中的 func
  3. 此時 D 對象自身還沒有構造, 此時 num 處在未初始化的狀態(tài), 值為 0.?
  4. 所以在構造函數內,盡量避免使用實例方法,除了finalprivate方法。
結論 : " 用盡量簡單的方式使對象進入可工作狀態(tài) ", 盡量不要在構造器中調用方法 ( 如果這個方法被子類重寫 , 就會觸發(fā)動態(tài)綁定, 但是此時子類對象還沒構造完成 ), 可能會出現(xiàn)一些隱藏的但是又極難發(fā)現(xiàn)的問題

到了這里,關于【JAVASE】帶你了解面向對象三大特性之一(多態(tài))的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • C++ 面向對象三大特性——多態(tài)

    C++ 面向對象三大特性——多態(tài)

    ?1主頁:我的代碼愛吃辣 ??2知識講解:C++ 繼承 ??3開發(fā)環(huán)境:Visual Studio 2022 ??4前言:面向對象三大特性的,封裝,繼承,多態(tài),今天我們研究研究 C++的多態(tài) 。 目錄 一.多態(tài)的概念 二.多態(tài)的定義及實現(xiàn) 1.多態(tài)的構成條件 2. 虛函數 3.虛函數的重寫 4. C++11 override 和 fina

    2024年02月12日
    瀏覽(91)
  • 【面向對象語言三大特性之 “多態(tài)”】

    【面向對象語言三大特性之 “多態(tài)”】

    目錄 ?1. 多態(tài)的概念 1.1 概念 2. 多態(tài)的定義及實現(xiàn) 2.1多態(tài)的構成條件 2.2 虛函數 ?2.3虛函數的重寫 2.4 C++11 override 和 final ?2.5 重載、覆蓋(重寫)、隱藏(重定義)的對比 ?3. 抽象類 3.1 概念 3.2 接口繼承和實現(xiàn)繼承 ?4.多態(tài)的原理 4.1虛函數表 ?4.2多態(tài)的原理 4.3 動態(tài)綁定與靜態(tài)綁定

    2023年04月17日
    瀏覽(56)
  • 【javaSE】 面向對象程序三大特性之繼承

    【javaSE】 面向對象程序三大特性之繼承

    目錄 為什么需要繼承 繼承的概念 繼承的語法 注意事項 ?父類成員訪問 子類中訪問父類的成員變量 子類和父類不存在同名成員變量 子類和父類成員變量同名 訪問原則 子類中訪問父類的成員方法 成員方法名字不同 總結: 成員方法名字相同 總結: super 注意事項 子類

    2024年02月14日
    瀏覽(25)
  • 【java】面向對象三大特性之多態(tài)

    【java】面向對象三大特性之多態(tài)

    ? ? ? ? 俗話說的好,“一龍生九子,九子各不同”,這句話就蘊含了面向對象三大特性之一的多態(tài)的思想。那么多態(tài)具體有什么特點呢,就由博主來帶大家梳理一下吧?? 目錄 一、什么是多態(tài) 二、重寫 三、向上轉型和向下轉型 1、向上轉型 2、向下轉型 四、多態(tài)的優(yōu)缺點

    2024年03月15日
    瀏覽(24)
  • 【JavaSE】面向對象之多態(tài)

    【JavaSE】面向對象之多態(tài)

    通俗來說,就是多種形態(tài),具體點就是去完成某個行為,當不同的對象去完成時會產生出不同的狀態(tài)。 必須要滿足如下幾個條件,缺一不可: 必須在 繼承 體系下 子類必須要對父類中方法進行 重寫 通過父類的引用調用重寫的方法 定義測試類TestAnimal.java 編譯器在編譯代碼時

    2024年02月11日
    瀏覽(24)
  • 面向對象詳解,面向對象的三大特征:封裝、繼承、多態(tài)

    面向對象詳解,面向對象的三大特征:封裝、繼承、多態(tài)

    一、面向對象與面向過程 面向對象編程 (Object-Oriented Programming,簡稱OOP)和 面向過程編程 (Procedural Programming,簡稱PP)是兩種不同的 編程范式 。 面向對象編程強調把問題分解成對象,通過封裝、繼承和多態(tài)等機制,來處理對象之間的關系 。每個對象都可以獨立地處理自

    2024年02月21日
    瀏覽(23)
  • 【JavaSE】面向對象編程思想之多態(tài)(圖文詳解)

    【JavaSE】面向對象編程思想之多態(tài)(圖文詳解)

    目錄 1.?多態(tài)的概念 2. 多態(tài)實現(xiàn)條件 3. 重寫 4. 向上轉型和向下轉型 4.1 向上轉型 4.2 向下轉型 5. 多態(tài)的優(yōu)缺點 6. 避免在構造方法中調用重寫的方法 多態(tài)的概念:通俗來說,就是多種形態(tài), 具體點就是去完成某個行為,當不同的對象去完成時會產生出不同的狀態(tài)。 ?總的來說

    2024年02月14日
    瀏覽(30)
  • C++:多態(tài)究竟是什么?為何能成為面向對象的重要手段之一?

    C++:多態(tài)究竟是什么?為何能成為面向對象的重要手段之一?

    本篇博客基于VS2019X86環(huán)境下,后續(xù)關于多態(tài)原理相關驗證都是基于vsX86環(huán)境,而虛表本質上是一個虛函數指針數組,在X86環(huán)境下VS編譯器會在數組最后放一個unllptr!! 多態(tài)的概念:通俗來說,就是多種形態(tài),具體點就是去 完成某個行為,當不同的對象去完成時會產生出不同的

    2024年02月02日
    瀏覽(19)
  • 【面向對象語言三大特性之 “繼承”】

    【面向對象語言三大特性之 “繼承”】

    目錄 1.繼承的概念及定義 1.1繼承的概念 1.2 繼承定義 1.2.1定義格式 ?1.2.2繼承關系和訪問限定符 ?1.2.3繼承基類成員訪問方式的變化 2.基類和派生類對象賦值轉換 3.繼承中的作用域 4.派生類的默認成員函數 5.繼承與友元 6. 繼承與靜態(tài)成員 7.復雜的菱形繼承及菱形虛擬繼承 8.繼

    2023年04月08日
    瀏覽(28)
  • C++ 面向對象三大特性——繼承

    C++ 面向對象三大特性——繼承

    ?1主頁:我的代碼愛吃辣 ??2知識講解:C++ 繼承 ??3開發(fā)環(huán)境:Visual Studio 2022 ??4前言:面向對象三大特性的,封裝,繼承,多態(tài),今天我們研究研究 C++的繼承 。 目錄 一.繼承的概念及定義 1.繼承的概念 ?2.繼承的定義 二. 繼承關系和訪問限定符 ?三.基類和派生類對象賦

    2024年02月12日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包