【Java】面向對象之多態超級詳解!!

文章目錄

  • 前言
  • 一、多態
    • 1.1 多態的概念
    • 1.2 多態的實現條件
    • 1.3 重寫
      • 1.3.1方法重寫的規則
      • 1.3.2重寫和重載的區別
    • 1.4 向上轉型和向下轉型
      • 1.4.1向上轉型
      • 1.4.2向下轉型
    • 1.5 多態的優缺點
      • 1.5.1 使用多態的好處
      • 1.5.2 使用多態的缺陷
  • 結語


前言

為了深入了解JAVA的面向對象的特性,今天繼續來學習剖析多態。多態在Java中的應用非常廣泛,它在繼承的前提下讓子類將父類中的方法進行重寫,最后通過父類對象訪問到子類重寫的方法實現。它可以大大優化代碼篇幅,讓代碼整體更清晰整潔,同時更方便使用者進行代碼的迭代更新!
提到了很多新內容,本篇文章將會詳細介紹Java語言中的多態概念,重寫,向上轉型和向下轉型等相關內容,讓我們速速開始吧!!

在這里插入圖片描述


看前提醒🚨:想要了解多態就先需要學習繼承,相關內容在該篇博客:【Java】面向對象之繼承超級詳解!!有詳細講解,學完再食用本篇博客效果更佳哦🌹🌹

一、多態

1.1 多態的概念

多態的概念:簡單來說,就是多種形態,去完成某個行為,當不同的對象去完成時會產生不同的狀態。

舉個栗子🌰!
自然界有各種動物,它們發出的聲音不盡相同,但都是做的發聲這個動作
在這里插入圖片描述
總而言之:同一件事,發生在不同對象身上,就會產生不同的結果。

那語言環境中如何實現多態?

1.2 多態的實現條件

在Java中如要實現多態,則需要滿足以下三個條件,缺一不可:

  1. 必須要在繼承的條件下
  2. 子類必須要對父類中的相關成員方法進行重寫
  3. 通過父類的引用調用重寫的方法

我們來看一段代碼:

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+"吃飯....");}
}
class Dog extends Animal{public Dog(String name,int age){super(name,age);}@Overridepublic void eat() {System.out.println(name + "正在吃狗糧.....");}
}class Cat extends Animal{public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name+"正在吃貓糧......");;}
}//*******************************************
public class test {static void eat(Animal A){A.eat();}public static void main(String[] args) {Dog dog = new Dog("沖沖",18);Cat cat = new Cat("JAVA",90);eat(dog);eat(cat);System.out.println("別忘了點贊三連支持歐o(>ω< )o!!!");}
}
//*******************
//運行結果:
//沖沖正在吃狗糧.....
//JAVA正在吃貓糧.....

我們可以看到同樣用eat方法最后輸出的內容卻不同。
當類的調用者在編寫eat方法的時候,參數類型為Animal(父類),此時該方法的內部并不知道也不關注當前的A引用指向的是哪種類型(哪個子類)的實例,則此時A引用調用eat方法時就可能會有不同的結果表現,而這種思想行為就稱為多態

1.3 重寫

在上面的實現條件中講到要對父類中的相關方法進行重寫,那么重寫又是什么呢?
重寫(Override):也稱之為覆蓋,覆寫。重寫是對子類對父類中類非靜態、非private修飾,非final修飾,非構造方法等的成員方法進行重新編寫。返回值,方法名和形參都不能改變! 即外殼不變,核心重寫。
重寫的好處在于能實現子類的需要,定義特定于自己的行為,也就是說子類能根據需要實現父類的方法。

1.3.1方法重寫的規則

  1. 子類在重寫父類對應方法時,一般必須與父類對應方法一致:返回值類型、形參(參數列表)、方法名
  2. 訪問權限不能比父類對應重寫方法的訪問權限更低
    例如:如果父類方法由protected修飾,則重寫的子類方法只能由protected或public修飾,否則重寫失敗😭
  3. 父類被static、private、final修飾的方法不能被重寫
  4. @Override 注解 重寫方法時可使用該注解來顯式指定,有了該注解可以幫我們在編寫代碼時進行一些合法性校驗。
    例如:編寫時不小心將eat打成了aet(出現了拼寫錯誤),那么此時編譯器就會發現父類中沒有aet方法,就會編譯報錯,提示無法進行重寫。

1.3.2重寫和重載的區別

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

重寫的設計原則
對于已經投入使用的類,盡量不要進行修改。最好的方法是:重復利用其中共性的內容,并且添加或者改動新的內容,實現迭代更新。

1.4 向上轉型和向下轉型

1.4.1向上轉型

實際上就是創建一個子類對象,將其當成父類對象來使用。
語法格式:父類類型 對象名 = new 子類類型()

Animal animal = new Cat("修貓",88);

animal是父類類型,但可以引用子類對象,因為是從大范圍中找小范圍的效果。

使用方法

  1. 直接賦值

    public static void main(String[] args) {Dog dog = new Dog("沖沖",18);Animal animal1 = dog;//這就屬于直接賦值animal1.eat();Cat cat = new Cat("JAVA",90);Animal animal2 = cat;animal2.eat();
    }
    
  2. 方法傳參

    static void eat(Animal A){A.eat();
    }
    public static void main(String[] args) {Dog dog = new Dog("沖沖",18);Cat cat = new Cat("JAVA",90);eat(dog);//這就是傳參實現向上轉型eat(cat);
    }
    
  3. 通過返回值,進行向上轉型

    Animal eat(){return new Cat("小貓",2);
    }
    

向上轉型的優點:讓代碼實現的更簡單靈活。
向上轉型的缺陷:不能調用到子類的特有方法。

1.4.2向下轉型

將一個子類對象進行向上轉型之后當成父類方法使用,在無法調用子類的方法,但有時候如果需要去調用子類特有的方法,我們就需要用到向下轉型:將父類引用再還原成子類對象即可。

我們再看一段代碼:

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+"吃飯....");}
}
class Dog extends Animal{public Dog(String name,int age){super(name,age);}@Overridepublic void eat() {System.out.println(name + "正在吃狗糧.....");}public void bark(){System.out.println(name+"正在旺旺叫.....");}
}class Cat extends Animal{public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name+"正在吃貓糧......");;}public void mew(){System.out.println(name+"正在喵喵叫.....");}
}public class down {public static void main(String[] args) {Cat cat = new Cat("小黑",2);Dog dog = new Dog("小橘", 1);Animal animal1 = cat;animal1.mew();Animal animal2 = dog;animal2.bark();}
}
//最后會編譯失敗,編譯時編譯器將animal當成Animal對象處理
//而Animal類中沒有bark和mew方法,因此編譯失敗

我們可以通過向下轉型操作實現:

//程序可以通過編程,但運行時拋出異常
//現在要強制還原
public class down {public static void main(String[] args) {Cat cat = new Cat("小黑",2);Dog dog = new Dog("小橘", 1);Animal animal1 = cat;//animal1.mew();cat = (Cat)animal1;//進行強制還原cat.mew();Animal animal2 = dog;//animal2.bark();dog = (Dog)animal2;dog.bark();}
}//編譯結果:
//小黑正在喵喵叫.....
//小橘正在旺旺叫.....

因向下轉型用的比較少,而且不安全,萬一轉換失敗,運行時就會拋出異常。Java為了提高向下轉型的安全性,引入了關鍵詞instanceof,如果表達式為true,則可安全轉換。

public class down {public static void main(String[] args) {Cat cat = new Cat("小黑",2);Dog dog = new Dog("小橘", 1);Animal animal1 = cat;Animal animal2 = dog;//animal1.mew();if(animal1 instanceof Cat){cat = (Cat)animal1;cat.mew();}//animal2.bark();if(animal2 instanceof Dog){dog = (Dog)animal2;dog.bark();}}
}

instanceof關鍵詞官方介紹:https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.20.2

1.5 多態的優缺點

1.5.1 使用多態的好處

  1. 能夠降低代碼的“圈復雜度”,避免使用大量的if-else

什么叫“圈復雜度”?
圈復雜度是一種描述一段代碼復雜程度的方式。一段代碼如果是平鋪直敘,那么就比較簡單容易理解,但如果有很多的條件分支或循環語句,則認為理解起來更復雜。
因此我們可以簡單粗暴的計算一段代碼中條件語句和循環語句出現的個數,結果個數就稱為“圈復雜度”。如果一個方法的圈復雜度臺稿,就需要考慮重構。

  1. 可擴展能力更強
    如果要增加一種新的功能,使用多態方式的代碼改動成本也比較低。

1.5.2 使用多態的缺陷

代碼的運行效率降低

  1. 屬性沒有多態性
    當父類和子類都有同名屬性的時候,通過父類引用,只能引用父類自己的成員屬性
  2. 構造方法沒有多態性
    盡量不要在構造器中調用方法,如果該方法被子類重寫,就會觸發動態綁定,而此時子類對象還沒構造完成,可能會出現一些隱藏而又極難發現的問題。

結語

好了那么以上就是本篇“【Java】面向對象之多態超級詳解!!”博客的全部內容啦,感謝各位的閱讀=v=,如有不足之處歡迎在評論區指出哦!!
覺得不錯的話別忘了點贊三連支持一下歐!拜托啦這對我真的很重要o(>ω< )o!!!

請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715414.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715414.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715414.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于yolov5的電瓶車和自行車檢測系統,可進行圖像目標檢測,也可進行視屏和攝像檢測(pytorch框架)【python源碼+UI界面+功能源碼詳解】

功能演示&#xff1a; 基于yolov5的電瓶車和自行車檢測系統_嗶哩嗶哩_bilibili &#xff08;一&#xff09;簡介 基于yolov5的電瓶車和自行車檢測系統是在pytorch框架下實現的&#xff0c;這是一個完整的項目&#xff0c;包括代碼&#xff0c;數據集&#xff0c;訓練好的模型…

協程庫項目—日志模塊

日志模塊程序結構圖 sylarLog ├── LogLevel&#xff08;日志級別封裝類&#xff09; │ ├── 提供“從日志級別枚舉值轉換到字符串”、“從字符串轉換相應的日志級別枚舉值”等方法 ├── LogEvent&#xff08;日志事件類&#xff09; │ ├── 封裝日志事件的屬性…

Unity(第二十一部)動畫的基礎了解(感覺不了解其實也行)

1、動畫組件老的是Animations 動畫視頻Play Automatically 是否自動播放Animate Physics 驅動方式&#xff0c;勾選后是物理驅動Culling Type 剔除方式 默認總是動畫化就會一直執行下去&#xff0c;第二個是基于渲染播放&#xff08;離開鏡頭后不執行&#xff09;&#xff0c; …

高性能服務系列【二】CPU和內存

現代計算機的系統架構十分復雜。在服務器中&#xff0c;雙路處理器已經十分常見。最近Arm處理器實現雙路共384核心&#xff0c;要知道目前Linux內核最高只支持256核&#xff0c;這就有點尷尬。 多路處理器將越來越普遍&#xff0c;對性能的影響和傳統架構有不小的差別&#xf…

MySQL中json類型的字段

有些很復雜的信息&#xff0c;我們一般會用擴展字段傳一個json串&#xff0c;字段一般用text類型存在數據庫。mysql5.7以后支持json類型的字段&#xff0c;還可以進行sql查詢與修改json內的某個字段的能力。 1.json字段定義 ip_info json DEFAULT NULL COMMENT ip信息, 2.按…

GO基本類型一些記錄

基本類型一些記錄 1.直接粘貼文本進println(" ")2.中文字符串長度別用len( )3.byte本質是uint8 1.直接粘貼文本進println(" ") GoLand會自動補充轉義符 2.中文字符串長度別用len( ) 用相應編碼庫的方法&#xff0c;一般utf8即可 utf8.RuneCountInStrin…

PySide6實現word轉化pdf

目錄 一:實現思路 二:實現代碼 三:完整代碼和界面 一:實現思路 利用PySide6創建兩個按鈕和一個顯示區域,一個選擇文件按鈕,一個轉化按鈕和信息展示,操作文件按鈕選擇一個待轉化的word文檔。并且展示文件路徑到信息展示區,操作轉化按鈕,讀取選擇的文件轉化為pdf。并…

ThreadLocal介紹

文章目錄 ThreadLocal源碼分析&#xff1a;set方法get方法remove方法 ThreadLocal內存泄漏問題 ThreadLocal ThreadLocal提供了線程局部變量&#xff0c;每個線程都可以通過set和get方法來對這個變量進行操作&#xff0c;但不會和其他線程的局部變量沖突&#xff0c;實現了線程…

Doris實戰——拈花云科的數據中臺實踐

目錄 前言 一、業務背景 二、數據中臺1.0—Lambda 三、新架構的設計目標 四、數據中臺2.0—Apache Doris 4.1 新架構數據流轉 4.2 新架構收益 五、新架構的落地實踐 5.1 模型選擇 5.1.1 Unique模型 5.1.2 Aggregate模型 5.2 資源管理 5.3 批量建表 5.4 計算實現…

Stable Diffusion 模型分享:Realistic Stock Photo(真實的庫存照片)

本文收錄于《AI繪畫從入門到精通》專欄&#xff0c;專欄總目錄&#xff1a;點這里。 文章目錄 模型介紹生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下載地址 模型介紹 條目內容類型大模型基礎模型SDXL 1.0來源CIVITAI作者PromptSharingSamaritan文件名稱reali…

原生GO開發的博客系統

Go博客實戰教程&#xff0c;是一個練手級項目教程&#xff0c;使用原生Go開發&#xff0c;未使用任何框架。 如何使用原生Go開發一個web項目 循序漸進&#xff0c;掌握編程思維和思路 初步具有工程思維&#xff0c;能適應一般的開發工作 1. 搭建項目 package mainimport (&q…

Vue3_2024_1天【Vue3創建和響應式,對比Vue2】

前言&#xff1a; Vue3對比Vue2版本&#xff0c;它在性能、功能、易用性和可維護性方面都有顯著的提升和改進。 性能優化&#xff1a;模板編譯器的優化、對Proxy的支持以及使用了更加高效的Virtual DOM算法等。這使得Vue3的打包大小減少了41%&#xff0c;初次渲染提速55%&#…

【MATLAB源碼-第153期】基于matlab的OFDM系統插入導頻和訓練符號兩種信道估計方式誤碼率對比仿真。

操作環境&#xff1a; MATLAB 2022a 1、算法描述 OFDM&#xff08;Orthogonal Frequency Division Multiplexing&#xff0c;正交頻分復用&#xff09;是一種高效的無線信號傳輸技術&#xff0c;廣泛應用于現代通信系統&#xff0c;如Wi-Fi、LTE和5G。OFDM通過將寬帶信道劃分…

使用docker方式測試部署django項目(客戶催)

需求 1&#xff1a;已有django項目–weidanyewu 2&#xff1a;希望在服務器上測試部署–客戶催 3&#xff1a;沒完善django的啟動 4&#xff1a;使用臨時數據庫進行演示 5&#xff1a;使用python3.10版本鏡像 6&#xff1a;展示端口80 7&#xff1a;后臺執行django程序 8&#…

【C語言】熟悉文件順序讀寫函數

前言 本篇詳細介紹了 文件順序讀寫常用函數&#xff0c;快來看看吧~ 歡迎關注個人主頁&#xff1a;逸狼 創造不易&#xff0c;可以點點贊嗎~ 如有錯誤&#xff0c;歡迎指出~ 目錄 前言 ?編輯 文件順序讀寫函數 fgetc函數 示例 fputc函數 逐個字符寫入 寫入26個字母 文…

手寫模擬器,解放雙手!效果炸裂的生產工具

手寫模擬器是一款基于Handright的仿手寫圖片生成軟件&#xff0c;可以讓你的電腦和手機也能寫出漂亮的手寫字&#xff0c;你只需要輸入你想要寫的內容&#xff0c;選擇你喜歡的字體和背景&#xff0c;就可以生成一張高仿真的手寫圖片&#xff0c;用于各種場合&#xff0c;比如做…

uniapp中canvas的基礎使用

canvas簡介 canvas是uniapp中提供的一個組件,用于生成自定義的圖形界面。通過canvas,我們可以通過JavaScript代碼在頁面上繪制各種圖形和圖像。 使用canvas 在頁面中添加canvas 首先需要在頁面的template中添加一個canvas組件: <template><view><canvas ca…

linux:iostat 用法詳解

文章目錄 描述語法參數例子 描述 iostat 是一個在類Unix操作系統中常用的系統監控工具&#xff0c;尤其是Linux系統中&#xff0c;它主要用于收集和報告中央處理器(CPU)使用情況以及磁盤輸入/輸出(I/O)統計數據。以下是 iostat 命令的基本用法及其參數詳解&#xff1a; 語法 …

代碼隨想錄三刷 day11 | 棧與隊列之 20. 有效的括號 1047. 刪除字符串中的所有相鄰重復項 150. 逆波蘭表達式求值

三刷day11 20. 有效的括號1047. 刪除字符串中的所有相鄰重復項150. 逆波蘭表達式求值 20. 有效的括號 題目鏈接 解題思路&#xff1a; 有三種不匹配的情況&#xff1a; 第一種情況&#xff0c;字符串里左方向的括號多余了 。 第二種情況&#xff0c;括號沒有多余&#xff0c;…

[伴學筆記]01-操作系統概述 [南京大學2024操作系統]

文章目錄 前言jyy:01-操作系統概述 [南京大學2024操作系統]為什么要學操作系統?學習操作系統能得到什么? 什么是操作系統?想要明白什么是操作系統:時間線:1940s1950s-1960s1960-1970s年代. 信息來源: 前言 督促自己,同時分享所得,閱讀完本篇大約需要10分鐘,希望為朋友的技術…