java面向?qū)ο罄^承與多態(tài)介紹
一.概述
面向?qū)ο蟪绦蛟O(shè)計(jì)的三大原則是封裝性,繼承性和多態(tài)性。繼承性是子類自動(dòng)共享父類的數(shù)據(jù)和方法的機(jī)制,它是由類的派生功能體現(xiàn)的。繼承具有傳遞性,使得一個(gè)類可以繼承另一個(gè)類的屬性和方法,這樣通過(guò)抽象出共同的屬性和方法組件新的類,便于代碼的重用。而多態(tài)是指不同類型的對(duì)象接收相同的消息時(shí)產(chǎn)生不同的行為,這里的消息主要是對(duì)類成員函數(shù)的調(diào)用,而不同的行為是指類成員函數(shù)的不同實(shí)現(xiàn)。當(dāng)對(duì)象接收到發(fā)送給它的消息時(shí),根據(jù)該對(duì)象所屬的類,動(dòng)態(tài)選用在該類中定義的實(shí)現(xiàn)算法。
二.繼承
2.1 繼承的概述
在現(xiàn)實(shí)中存在很多如圖所示的關(guān)系:

出租車,卡車和公交車都是汽車的一種,分別擁有相似的特征。例如,引擎的數(shù)量,外觀顏色等。它們擁有相似的行為,如剎車和加速的功能。但是每種不同的交通工具又有自己的特征,如公交車擁有和其他交通工具不同的特性和行為——最大載客數(shù)量和到指定站點(diǎn)要報(bào)站的特點(diǎn),而卡車的主要功能是送貨物,也就是載貨和卸貨,因此擁有最大載重量的特性。
在面向?qū)ο蟮某绦蛟O(shè)計(jì)中該怎樣描述現(xiàn)實(shí)世界的這種狀況呢?這就用到繼承的概念。
所謂繼承,就是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴(kuò)展新的能力。已有的類一般稱為父類(基類或超類),這個(gè)過(guò)程也稱為類的派生。由基類產(chǎn)生的新類稱為派生類或子類,派生類同樣可以作為基類再派生新的子類,這樣就形成了類間的層次結(jié)構(gòu)。
基類和派生類類的關(guān)系如下:
* 基類是派生類的抽象(基類抽象了派生類的公共特征)。
* 派生類是對(duì)基類的擴(kuò)展。
* 派生類和基類的關(guān)相當(dāng)于“是一個(gè)(is a)”的關(guān)系,即派生類是基類的一個(gè)對(duì)象,而不是“有(has)”的關(guān)系,即類的對(duì)象包含一個(gè)或多個(gè)其他類的對(duì)象作為該類的屬性。
2.2 繼承機(jī)制
定義教師類,其中一類教師為Net教師,屬性為姓名,所屬部門,方法為授課,自我介紹。
public class NetTeacher {
private String name;
private String school;
public NetTeacher(String myName,String mySchool){
name = myName;
school = mySchool;
}
public void giveLession(){
System.out.println("啟動(dòng) VS2021 ");
System.out.println("知識(shí)點(diǎn)講解");
System.out.println("總結(jié)提問");
}
public void introduction(){
System.out.println("大家好!我是" + schoool + "的" + name + " 。");
}
}定義教師類,其中一類教師為Java教師,屬性為姓名,所屬部門,方法為授課,自我介紹。
public class JavaTeacher {
private String name;
private String school;
public JavaTeacher(String myName,String mySchool){
name = myName;
school = mySchool;
}
public void giveLession(){
System.out.println("啟動(dòng) IDEA2021 ");
System.out.println("知識(shí)點(diǎn)講解");
System.out.println("總結(jié)提問");
}
public void introduction(){
System.out.println("大家好!我是" + schoool + "的" + name + " 。");
}
}在程序處理中,發(fā)現(xiàn)兩個(gè)類的定義非常相似,有很多相同點(diǎn),如教師的屬性姓名,所屬部門類似,類的方法也基本相同。
針對(duì)這種情況,將Java教師類和Net教師類的共性抽取出來(lái),形成父類Teacher類,使得Net教師和Java教師成為Teacher類的子類,則子類繼承父類的基本屬性和方法,就簡(jiǎn)化了子類的定義。上述代碼可以修改如下:
public class Teacher {
private String name;
private String school;
public Teacher(String myName,String mySchool){
name = myName;
school = mySchool;
}
public void giveLession(){
System.out.println("知識(shí)點(diǎn)講解");
System.out.println("總結(jié)提問");
}
public void introduction(){
System.out.println("大家好!我是" + schoool + "的" + name + " 。");
}
}
子類JavaTeacher:
public class JavaTeacher extends Teacher {
public JavaTeacher(String myName,String mySchool){
super(myName,mySchool);
}
public void giveLession(){
System.out.println("啟動(dòng) IDEA2021 ");
super.giveLession;
}
子類NetTeacher:
public class NetTeacher extends Teacher {
public NetTeacher(String myName,String mySchool){
super(myName,mySchool);
}
public void giveLession(){
System.out.println("啟動(dòng) VS2021 ");
super.giveLession;
}子類自動(dòng)繼承父類的屬性和方法,子類中不再存在重復(fù)代碼,從而實(shí)現(xiàn)代碼的重用。
通過(guò)關(guān)鍵字 extends,分別創(chuàng)建父類 Teacher 的子類 JavaTeacher 和 NetTecher 。子類繼承父類所有的成員變量和成員方法,但不能繼承父類的構(gòu)造方法。在子類的構(gòu)造方法中,可使用語(yǔ)句super (參數(shù)列表)調(diào)用父類的構(gòu)造方法,如子類構(gòu)造方法中的語(yǔ)句 super(myName,mySchool)。
extends 說(shuō)明要構(gòu)建一個(gè)新類,該類從已存在的類派生而來(lái)。派生的定義過(guò)程,實(shí)際是經(jīng)歷了以下幾個(gè)過(guò)程:
*子類繼承父類中被聲明為 public 和 protected 的成員變量和成員方法,但是不能繼承被聲明為 private 的成員變量和成員方法。
*重寫父類成員,包括數(shù)據(jù)成員和成員函數(shù)。如果子類聲明了一個(gè)與父類成員函數(shù)相同的成員函數(shù),子類中的新成員則屏蔽了父類同名成員,類似函數(shù)中的局部變量屏蔽了全局變量,稱為同名覆蓋(Overriding)。
*定義新成員。新成員是派生類自己的新特性。派生類新成員的加入使得派生類在功能上有所發(fā)展。
*必須在派類中重寫構(gòu)造方法,因?yàn)闃?gòu)造方法不能繼承。
2.3 類中屬性,方法的繼承與覆蓋
1.屬性的繼承與覆蓋
子類可以繼承父類的所有非私有屬性。
子類也可以覆蓋繼承的成員變量,對(duì)于子類可以從父類繼承的成員變量,只要子類中定義的成員變量和父類中的成員變量同名,子類就覆蓋了繼承的成員變量。
當(dāng)子類執(zhí)行它自己定義的方法時(shí),所操作的就是它自己定義的數(shù)據(jù)成員,,從而覆蓋父類繼承來(lái)的數(shù)據(jù)成員。
2.方法的繼承與覆蓋
父類中非私有( private )方法可以被子類所繼承。
在子類繼承父類的成員方法時(shí),應(yīng)注意一下兩項(xiàng):
*子類不能訪問父類的 private 成員方法,但子類可以訪問父類的 piblic ,protected 成員方法。
*訪問 protected 時(shí),子類和同一包內(nèi)的方法都能訪問父類的 protected 成員方法,但其他方法不能訪問。
方法的覆蓋是指子類中定義一個(gè)方法,并且這個(gè)方法的名字,返回類型,參數(shù)列表與父類繼承的方法完全相同。
2.4 super 關(guān)鍵字
子類不能繼承父類的構(gòu)造方法。
如果基類中沒有默認(rèn)構(gòu)造方法或希望調(diào)用帶參數(shù)的基類構(gòu)造方法,要使用關(guān)鍵字 super 來(lái)顯示調(diào)用基類構(gòu)造方法。使用關(guān)鍵字 super 調(diào)用基類構(gòu)造方法的語(yǔ)句,必須是子類構(gòu)造方法的第一個(gè)可執(zhí)行語(yǔ)句。調(diào)用基類構(gòu)造方法時(shí),傳遞的參數(shù)不能是關(guān)鍵字 this 或當(dāng)前對(duì)象的非靜態(tài)成員。
super 關(guān)鍵字主要應(yīng)用于繼承關(guān)系實(shí)現(xiàn)子類對(duì)父類方法的調(diào)用,包括對(duì)父類構(gòu)造方法和一般方法的調(diào)用。具體使用方法如下:
(1)子類的構(gòu)造方法如果要引用 super ,必須把 super 放在構(gòu)造方法的第一個(gè)可執(zhí)行語(yǔ)句。例如:
public CommonEmployee (String name,double bonus){
super (name); //通過(guò) super () 的調(diào)用,給父類的數(shù)據(jù)成員賦初值
this.bonus = bonus; // this 指當(dāng)前對(duì)象
System.out.println("子類構(gòu)造方法的調(diào)用");
}(2)在 Java 中,有時(shí)還會(huì)遇到子類中的成員變量或方法與父類中的成員變量或方法同名。同名子類中的成員變量或方法名優(yōu)先級(jí)高,所以子類中的同名成員變量或方法覆蓋了父類的成員變量或方法,但是我們?nèi)绻胍褂酶割愔械倪@個(gè)成員變量或方法,就需要用到 super .
(3)可以用 super 直接傳遞參數(shù)。見下面代碼:
public class Person {
Person(){
prt("A Person.");
}
Person(String name){
prt("A person name is:" + name);
}
public static void prt(String s){
System.out.println(s);
}
}
public class Chinese extends Person {
Chinese(){
super(); //調(diào)用父類無(wú)形參構(gòu)造方法
prt("A chinese"); //調(diào)用父類的方法prt
}
Chinese(String name){
super(name); //調(diào)用父類具有相同形參的構(gòu)造方法
prt("his name is:" + name);
}
Chinese(String name,int age){
this(name); //調(diào)用當(dāng)前具有相同形參的構(gòu)造方法
prt("his age is:" + age);
}
public static void main(String[] args) {
Chinese cn = new Chinese();
cn = new Chinese("Kevin");
cn = new Chinese("Jhone",21);
}
}
程序分析如下:
●main()中首先構(gòu)建Chinese的第一個(gè)對(duì)象cn, 語(yǔ)句cn = new Chinese()調(diào)用子類無(wú)參的構(gòu)造方法Chinese(),在構(gòu)造方法中super()語(yǔ)句調(diào)用父類的無(wú)參構(gòu)造方法Person(),在父類無(wú)參的構(gòu)造方法中調(diào)用父類的方法prt(),程序輸出結(jié)果A Person,接下來(lái)返回子類的構(gòu)造方法的調(diào)用處,繼續(xù)執(zhí)行下面的語(yǔ)句pr("A chinese."),則調(diào)用父類的方法prt輸出結(jié)果A chinese.結(jié)束第一條語(yǔ)句。
●程序繼續(xù)執(zhí)行第二條語(yǔ)句cn = new Chinese("kevin");此時(shí)調(diào)用子類具有一 個(gè)參數(shù)參的構(gòu)造方法Chinese(name),在構(gòu)造方法中super(name)語(yǔ)句調(diào)用父類的有參構(gòu)造方法prt("A person name is:"+ name),程序輸出結(jié)果A person name is:kevin,接下來(lái)返回子類的構(gòu)造方法的調(diào)用處,繼續(xù)執(zhí)行下面的語(yǔ)句prt("his name is:"+ name),則調(diào)用父類的方法prt輸出結(jié)果his name is:kevin,結(jié)束第二條語(yǔ)句。
●接下來(lái)程序繼續(xù)執(zhí)行第三條語(yǔ)句cn = new Chinese("Jhone,"22);程序執(zhí)行時(shí)先調(diào)用子類具有兩個(gè)參數(shù)參的構(gòu)造方法Chinese(name, age), 在構(gòu)造方法中this ( name )語(yǔ)句則調(diào)用的是當(dāng)前具有相同參數(shù)的構(gòu)造方法,即調(diào)用子類具有一個(gè)參數(shù)參的構(gòu)造方法Chinese(name),接下來(lái)調(diào)用父類的有參構(gòu)造方法Person(name),為父類的name進(jìn)行初始化,再接下來(lái)在父類有參的構(gòu)造方法中調(diào)用父類的方法prt("A person name is:"+ name),程序輸出結(jié)果A person name is: Jhone,接下來(lái)返回子類的構(gòu)造方法的調(diào)用處,繼續(xù)執(zhí)行下面的語(yǔ)句prt("his name is:"+ name),則調(diào)用父類的方法prt輸出結(jié)果his name is: Jhone,調(diào)用結(jié)束后程序返回子類構(gòu)造方法Chinese(name,age)執(zhí)行語(yǔ)句prt("his age is:"+ age); 輸出結(jié)果his age is:22,結(jié)束第二條語(yǔ)句。

三. 多態(tài)
多態(tài)是指在父類中定義的屬性和方法被子類繼承之后,可以具有不同的數(shù)據(jù)類型或表現(xiàn)出不同的行為,這使得同一個(gè)屬性或方法在父類及其各個(gè)子類中具有不同的含義。
對(duì)面向?qū)ο髞?lái)說(shuō),多態(tài)分為編譯時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)。其中編譯時(shí)多態(tài)是靜態(tài)的,主要是指方法的重載,它是根據(jù)參數(shù)列表的不同來(lái)區(qū)分不同的方法。通過(guò)編譯之后會(huì)變成兩個(gè)不同的方法,在運(yùn)行時(shí)談不上多態(tài)。而運(yùn)行時(shí)多態(tài)是動(dòng)態(tài)的,它是通過(guò)動(dòng)態(tài)綁定來(lái)實(shí)現(xiàn)的,也就是大家通常所說(shuō)的多態(tài)性。
Java 實(shí)現(xiàn)多態(tài)有 3 個(gè)必要條件:繼承、重寫和向上轉(zhuǎn)型。只有滿足這 3 個(gè)條件,開發(fā)人員才能夠在同一個(gè)繼承結(jié)構(gòu)中使用統(tǒng)一的邏輯實(shí)現(xiàn)代碼處理不同的對(duì)象,從而執(zhí)行不同的行為。
繼承:在多態(tài)中必須存在有繼承關(guān)系的子類和父類。重寫:子類對(duì)父類中某些方法進(jìn)行重新定義,在調(diào)用這些方法時(shí)就會(huì)調(diào)用子類的方法。向上轉(zhuǎn)型:在多態(tài)中需要將子類的引用賦給父類對(duì)象,只有這樣該引用才既能可以調(diào)用父類的方法,又能調(diào)用子類的方法。
總結(jié)
到此這篇關(guān)于java面向?qū)ο罄^承與多態(tài)介紹的文章就介紹到這了,更多相關(guān)java繼承與多態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis Mybatis-Plus傳入多個(gè)參數(shù)的處理方式
這篇文章主要介紹了Mybatis Mybatis-Plus傳入多個(gè)參數(shù)的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Apache?Arrow?Parquet存儲(chǔ)與使用
這篇文章主要為大家介紹了Apache?Arrow?Parquet存儲(chǔ)與使用原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
詳解SpringBoot AOP 攔截器(Aspect注解方式)
這篇文章主要介紹了詳解SpringBoot AOP 攔截器 Aspect,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
淺析fastjson2時(shí)間序列化和反序列化的簡(jiǎn)單使用
在項(xiàng)目中將fastjson升級(jí)為fastjson2后,我們遇到了一些與fastjson不完全兼容的問題,所以本文就來(lái)探討下fastjson2的時(shí)間序列化和反序列化的簡(jiǎn)單使用吧2025-01-01
AgileBoot?項(xiàng)目?jī)?nèi)統(tǒng)一的錯(cuò)誤碼設(shè)計(jì)分析
這篇文章主要為大家介紹了AgileBoot?項(xiàng)目?jī)?nèi)統(tǒng)一的錯(cuò)誤碼設(shè)計(jì)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
java結(jié)合WebSphere MQ實(shí)現(xiàn)接收隊(duì)列文件功能
WebSphereMQ,也稱MQSeries,以一致的、可靠的和易于管理的方式來(lái)連接應(yīng)用程序,并為跨部門、企業(yè)范圍的集成提供了可靠的基礎(chǔ)。通過(guò)為重要的消息和事務(wù)提供可靠的、一次且僅一次的傳遞,MQ可以處理復(fù)雜的通信協(xié)議,并動(dòng)態(tài)地將消息傳遞工作負(fù)載分配給可用的資源。2015-10-10
Mybatis如何獲取insert新增數(shù)據(jù)id值
這篇文章主要介紹了Mybatis如何獲取insert新增數(shù)據(jù)id值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
SpringBoot @PathVariable使用時(shí)遇到的問題及解決
這篇文章主要介紹了SpringBoot @PathVariable使用時(shí)遇到的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10

