摘要:多態(tài)的前提是必須有子父類關(guān)系或者類實現(xiàn)接口關(guān)系,否則無法完成多態(tài)。具體格式如下父類引用指向子類對象就是多態(tài)的定義格式。多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種向上轉(zhuǎn)型當(dāng)有子類對象賦值給一個父類引用時,便是向上轉(zhuǎn)型,多態(tài)本身就是向上轉(zhuǎn)型的過程。
第3天 面向?qū)ο?/p>
今日內(nèi)容介紹
? 接口
? 多態(tài)
? 筆記本案例
今日學(xué)習(xí)目標(biāo)
? 寫出定義接口的格式
? 寫出實現(xiàn)接口的格式
? 說出接口中成員的特點
? 接口和抽象類的區(qū)別
? 能夠說出使用多態(tài)的前提條件
? 理解多態(tài)的向上轉(zhuǎn)型
? 理解多態(tài)的向下轉(zhuǎn)型
? 能夠完成筆記本電腦案例(方法參數(shù)為接口)
第1章 接口
1.1 接口概念
類:具有相同屬性和功能的事物集合
接口是功能的集合,同樣可看做是一種數(shù)據(jù)類型,是比抽象類更為抽象的”類”。
接口只描述所應(yīng)該具備的方法,并沒有具體實現(xiàn),具體的實現(xiàn)由接口的實現(xiàn)類(相當(dāng)于接口的子類)來完成。這樣將功能的定義與實現(xiàn)分離,優(yōu)化了程序設(shè)計。
請記?。阂磺惺挛锞泄δ?,即一切事物均有接口。
1.2 接口的定義
與定義類的class不同,接口定義時需要使用interface關(guān)鍵字。
定義接口所在的仍為.java文件,雖然聲明時使用的為interface關(guān)鍵字的編譯后仍然會產(chǎn)生.class文件。這點可以讓我們將接口看做是一種只包含了功能聲明的特殊類。
定義格式:
public interface 接口名 {
抽象方法1;
抽象方法2;
抽象方法3;
}
使用interface代替了原來的class,其他步驟與定義類相同:
? 接口中的方法均為公共訪問的抽象方法
? 接口中無法定義普通的成員變量
1.3 類實現(xiàn)接口
類與接口的關(guān)系為實現(xiàn)關(guān)系,即類實現(xiàn)接口。實現(xiàn)的動作類似繼承,只是關(guān)鍵字不同,實現(xiàn)使用implements。
其他類(實現(xiàn)類)實現(xiàn)接口后,就相當(dāng)于聲明:”我應(yīng)該具備這個接口中的功能”。實現(xiàn)類仍然需要重寫方法以實現(xiàn)具體的功能。
格式:
class 實現(xiàn)類 implements 接口 {
重寫接口中所有方法
}
在類實現(xiàn)接口后,該類就會將接口中的抽象方法繼承過來,此時該類需要重寫該抽象方法,完成具體的邏輯。
? 接口中定義功能,當(dāng)需要具有該功能時,可以讓類實現(xiàn)該接口,只聲明了應(yīng)該具備該方法,是功能的聲明。
? 在具體實現(xiàn)類中重寫方法,實現(xiàn)功能,是方法的具體實現(xiàn)。
于是,通過以上兩個動作將功能的聲明與實現(xiàn)便分開了。(此時請重新思考:類是現(xiàn)實事物的描述,接口是功能的集合。)
1.4 接口中成員的特點
1、接口中可以定義成員變量,但是變量必須有固定的修飾符修飾,public static final 所以接口中的變量也稱之為常量,其值不能改變。后面我們會講解static與final關(guān)鍵字
2、接口中可以定義方法,方法也有固定的修飾符,public abstract
3、接口不可以創(chuàng)建對象。
4、實現(xiàn)類必須覆蓋掉接口中所有的抽象方法后,實現(xiàn)類才可以實例化。否則實現(xiàn)類是一個抽象類。
interface Demo { ///定義一個名稱為Demo的接口。 public static final int NUM = 3;// NUM的值不能改變 public abstract void show1(); public abstract void show2(); } //定義子類去覆蓋接口中的方法。類與接口之間的關(guān)系是 實現(xiàn)。通過 關(guān)鍵字 implements class DemoImpl implements Demo { //子類實現(xiàn)Demo接口。 //重寫接口中的方法。 public void show1(){} public void show2(){} }
1.5 接口特點
? 接口可以繼承接口
如同類繼承類后便擁有了父類的成員,可以使用父類的非私有成員。A接口繼承B接口后,A接口便擁有了A、B兩個接口中所有的抽象方法。
? Java支持一個類同時實現(xiàn)多個接口,或一個接口同時繼承多個接口。
? 類可以在繼承一個類的同時,實現(xiàn)多個接口。
? 接口與父類的功能可以重復(fù),均代表要具備某種功能,并不沖突。
1.6 接口和抽象類的區(qū)別*
明白了接口思想和接口的用法后,接口和抽象類的區(qū)別是什么呢?接口在生活體現(xiàn)也基本掌握,那在程序中接口是如何體現(xiàn)的呢?
通過實例進行分析和代碼演示抽象類和接口的用法。
1、舉例:
犬:
行為:
吼叫; 吃飯;
緝毒犬:
行為:
吼叫; 吃飯; 緝毒;
2、思考:
由于犬分為很多種類,他們吼叫和吃飯的方式不一樣,在描述的時候不能具體化,也就是吼叫和吃飯的行為不能明確。當(dāng)描述行為時,行為的具體動作不能明確,這時,可以將這個行為寫為抽象行為,那么這個類也就是抽象類。
可是當(dāng)緝毒犬有其他額外功能時,而這個功能并不在這個事物的體系中。這時可以讓緝毒犬具備犬科自身特點的同時也有其他額外功能,可以將這個額外功能定義接口中。
如下代碼演示:
interface 緝毒{ public abstract void 緝毒(); } //定義犬科的這個提醒的共性功能 abstract class 犬科{ public abstract void 吃飯(); public abstract void 吼叫(); } // 緝毒犬屬于犬科一種,讓其繼承犬科,獲取的犬科的特性, //由于緝毒犬具有緝毒功能,那么它只要實現(xiàn)緝毒接口即可,這樣即保證緝毒犬具備犬科的特性,也擁有了緝毒的功能 class 緝毒犬 extends 犬科 implements 緝毒{ public void 緝毒() { } void 吃飯() { } void 吼叫() { } } class 緝毒豬 implements 緝毒{ public void 緝毒() { } }
3、通過上面的例子總結(jié)接口和抽象類的區(qū)別:
相同點:
? 都位于繼承的頂端,用于被其他類實現(xiàn)或繼承;
? 都不能直接實例化對象;
? 都可以包含抽象方法,其子類都必須覆寫這些抽象方法;
區(qū)別:
? 抽象類為部分方法提供實現(xiàn),避免子類重復(fù)實現(xiàn)這些方法,提高代碼重用性;
? 接口只能包含抽象方法;
? 一個類只能繼承一個直接父類(可能是抽象類),卻可以實現(xiàn)多個接口;(接口彌補了Java的單繼承)
? 抽象類為繼承體系中的共性內(nèi)容,接口為繼承體系外的擴展功能
二者的選用:
? 優(yōu)先選用接口,盡量少用抽象類;
? 需要定義子類的行為,又要為子類提供共性功能時才選用抽象類;
第2章 多態(tài)
2.1 多態(tài)概述
多態(tài)是繼封裝、繼承之后,面向?qū)ο蟮牡谌筇匦浴?br>現(xiàn)實事物經(jīng)常會體現(xiàn)出多種形態(tài),如學(xué)生,學(xué)生是人的一種,則一個具體的同學(xué)張三既是學(xué)生也是人,即出現(xiàn)兩種形態(tài)。
Java作為面向?qū)ο蟮恼Z言,同樣可以描述一個事物的多種形態(tài)。如Student類繼承了Person類,一個Student的對象便既是Student,又是Person。
Java中多態(tài)的代碼體現(xiàn)在一個子類對象(實現(xiàn)類對象)既可以給這個子類(實現(xiàn)類對象)引用變量賦值,又可以給這個子類(實現(xiàn)類對象)的父類(接口)變量賦值。
如Student類可以為Person類的子類。那么一個Student對象既可以賦值給一個Student類型的引用,也可以賦值給一個Person類型的引用。
最終多態(tài)體現(xiàn)為父類引用變量可以指向子類對象。
多態(tài)的前提是必須有子父類關(guān)系或者類實現(xiàn)接口關(guān)系,否則無法完成多態(tài)。
在使用多態(tài)后的父類引用變量調(diào)用方法時,會調(diào)用子類重寫后的方法。
2.2 多態(tài)代碼體現(xiàn)
Java中多態(tài)的代碼體現(xiàn)在一個子類對象(實現(xiàn)類對象)既可以給這個子類(實現(xiàn)類對象)引用變量賦值,又可以給這個子類(實現(xiàn)類對象)的父類(接口)變量賦值。
如Student類可以為Person類的子類。那么一個Student對象既可以賦值給一個Student類型的引用,也可以賦值給一個Person類型的引用。
最終多態(tài)體現(xiàn)為父類引用變量可以指向子類對象。
多態(tài)的前提是必須有子父類關(guān)系或者類實現(xiàn)接口關(guān)系,否則無法完成多態(tài)。
在使用多態(tài)后的父類引用變量調(diào)用方法時,會調(diào)用子類重寫后的方法。
具體格式如下:
父類引用指向子類對象就是多態(tài)的定義格式。同一個父類的方法會被不同的子類重寫為各自的具體實現(xiàn)。在調(diào)用方法時,調(diào)用的為各個子類重寫后的方法。
父類類型 變量名 = new 子類類型();
變量名.方法名();
此時,雖然該變量指向的是子類對象,但表現(xiàn)為一個父類的形態(tài),可以調(diào)用一切父類的方法,子類特有的方法將不能調(diào)用。
2.3 多態(tài)調(diào)用注意事項
? 成員變量編譯看父類中是否存在,不存在編譯失敗
? 成員變量運行父類中的變量
? 成員方法編譯看父類中是否存在,不存在編譯失敗
? 成員方法運行子類重寫的方法
2.4 多態(tài)的好處和弊端(貓狗的案例)**
當(dāng)變量名指向不同的子類對象時,由于每個子類重寫父類方法的內(nèi)容不同,所以會調(diào)用不同的方法。
如:
在Boss類中,有叫員工去工作的方法,當(dāng)該方法的參數(shù)定義為接口時,可以傳入任意的子類對象。相比定義多個子類參數(shù),定義多個方法,這樣大大提高了代碼復(fù)用性與擴展性。
class Boss{ public void goToWork(Empolyee e){ e.work(); } }
所以多態(tài)的存在意義(優(yōu)點)為:
配合繼承與方法重寫提高了代碼的復(fù)用性與擴展性,如果沒有方法重寫,則多態(tài)同樣沒有意義。
多態(tài)的弊端: 不能調(diào)用子類的特有方法
2.5 向上向下類型轉(zhuǎn)換
多態(tài)本身是子類類型向父類類型向上轉(zhuǎn)型的過程。
多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:
? 向上轉(zhuǎn)型:當(dāng)有子類對象賦值給一個父類引用時,便是向上轉(zhuǎn)型,多態(tài)本身就是向上轉(zhuǎn)型的過程。
使用格式:
父類類型 變量名 = new 子類類型();
如:Animal p = new Cat();
? 向下轉(zhuǎn)型:一個已經(jīng)向上轉(zhuǎn)型的子類對象可以使用強制類型轉(zhuǎn)換的格式,將父類引用轉(zhuǎn)為子類引用,這個過程是向下轉(zhuǎn)型。如果是直接創(chuàng)建父類對象,是無法向下轉(zhuǎn)型的!
使用格式:
子類類型 變量名 = (子類類型) 父類類型的變量;
如:Cat c = (Cat) a; //變量p 實際上指向Cat對象
? instanceof關(guān)鍵字
使用格式:
boolean b = 引用變量 instanceof 類;
if(a instanceof Dog){
Dog d = (Dog)a;
}
第3章 筆記本電腦案例
3.1 案例介紹
定義USB接口(具備開啟功能、關(guān)閉功能),筆記本要使用USB設(shè)備,即筆記本在生產(chǎn)時需要預(yù)留可以插入USB設(shè)備的USB接口,即就是筆記本具備使用USB設(shè)備的功能,但具體是什么USB設(shè)備,筆記本并不關(guān)心,只要符合USB規(guī)格的設(shè)備都可以。鼠標(biāo)和鍵盤要想能在電腦上使用,那么鼠標(biāo)和鍵盤也必須遵守USB規(guī)范,不然鼠標(biāo)和鍵盤的生產(chǎn)出來無法使用
進行描述筆記本類,實現(xiàn)筆記本使用USB鼠標(biāo)、USB鍵盤
? USB接口,包含開啟功能、關(guān)閉功能
? 筆記本類,包含運行功能、關(guān)機功能、使用USB設(shè)備功能
? 鼠標(biāo)類,要符合USB接口
? 鍵盤類,要符合USB接口
3.2 案例需求分析
階段一:
使用筆記本,筆記本有運行功能,需要筆記本對象來運行這個功能
階段二:
想使用一個鼠標(biāo),又有一個功能使用鼠標(biāo),并多了一個鼠標(biāo)對象。
階段三:
還想使用一個鍵盤 ,又要多一個功能和一個對象
問題:每多一個功能就需要在筆記本對象中定義一個方法,不爽,程序擴展性極差。
降低鼠標(biāo)、鍵盤等外圍設(shè)備和筆記本電腦的耦合性。
3.3 實現(xiàn)代碼步驟
? 定義鼠標(biāo)、鍵盤,筆記本三者之間應(yīng)該遵守的規(guī)則
interface USB {
void open();// 開啟功能 void close();// 關(guān)閉功能
}
? 鼠標(biāo)實現(xiàn)USB規(guī)則
class Mouse implements USB {
publicvoid open() { System.out.println("鼠標(biāo)開啟"); } publicvoid close() { System.out.println("鼠標(biāo)關(guān)閉"); }
}
? 鍵盤實現(xiàn)USB規(guī)則
class KeyBoard implements USB {
publicvoid open() { System.out.println("鍵盤開啟"); } publicvoid close() { System.out.println("鍵盤關(guān)閉"); }
}
? 定義筆記本
class NoteBook { // 筆記本開啟運行功能 publicvoid run() { System.out.println("筆記本運行"); } // 筆記本使用usb設(shè)備,這時當(dāng)筆記本對象調(diào)用這個功能時,必須給其傳遞一個符合USB規(guī)則的USB設(shè)備 publicvoid useUSB(USB usb) { // 判斷是否有USB設(shè)備 if (usb != null) { usb.open(); usb.close(); } } publicvoid shutDown() { System.out.println("筆記本關(guān)閉"); } } publicclass Test { publicstaticvoid main(String[] args) { // 創(chuàng)建筆記本實體對象 NoteBook nb = new NoteBook(); // 筆記本開啟 nb.run(); // 創(chuàng)建鼠標(biāo)實體對象 Mouse m = new Mouse(); // 筆記本使用鼠標(biāo) nb.useUSB(m); // 創(chuàng)建鍵盤實體對象 KeyBoard kb = new KeyBoard(); // 筆記本使用鍵盤 nb.useUSB(kb); // 筆記本關(guān)閉 nb.shutDown(); } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73153.html
摘要:現(xiàn)代的面向?qū)ο蟮乃枷氩粡娬{(diào)為真實世界建模變得更加理性化一些,把目標(biāo)放在解耦上。各種語言中的多態(tài)多態(tài)確切的含義是同一類的對象收到相同消息時,會得到不同的結(jié)果。小結(jié)本章主要介紹面向?qū)ο笏枷氲某绦虻慕M成元素類和對象。 第一章 面向?qū)ο笏枷氲暮诵母拍?showImg(https://segmentfault.com/img/bVNfjM?w=673&h=334); showImg(https:...
摘要:抽象數(shù)據(jù)類型的多個不同表示可以共存于同一個程序中,作為實現(xiàn)接口的不同類。封裝和信息隱藏信息隱藏將精心設(shè)計的模塊與不好的模塊區(qū)分開來的唯一最重要的因素是其隱藏內(nèi)部數(shù)據(jù)和其他模塊的其他實施細節(jié)的程度。 大綱 面向?qū)ο蟮臉?biāo)準(zhǔn)基本概念:對象,類,屬性,方法和接口OOP的獨特功能 封裝和信息隱藏 繼承和重寫 多態(tài)性,子類型和重載 靜態(tài)與動態(tài)分派 Java中一些重要的Object方法設(shè)計好的類面向...
摘要:實現(xiàn)多態(tài)的三個必要條件繼承在多態(tài)中必須存在有繼承關(guān)系的子類和父類。參考面試題解惑系列九繼承多態(tài)重載和重寫面向?qū)ο笕筇匦苑庋b,繼承,多態(tài)以及抽象接口的介紹 版權(quán)聲明:本文由吳仙杰創(chuàng)作整理,轉(zhuǎn)載請注明出處:https://segmentfault.com/a/1190000009141566 1. 面向?qū)ο缶幊痰娜筇匦?Java 面向?qū)ο缶幊逃腥筇匦裕悍庋b、繼承、多態(tài)。 1.1 封裝...
摘要:單一職責(zé)原則可以看做是低耦合高內(nèi)聚在面向?qū)ο笤瓌t上的引申,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性來減少引起變化的原因。抽象的穩(wěn)定性決定了系統(tǒng)的穩(wěn)定性,因為抽象是不變的,依賴于抽象是面向?qū)ο笤O(shè)計的精髓,也是依賴倒置原則的核心。 Java-面向?qū)ο?什么是面過程 把題分解成一個一個步驟,每個步驟用函數(shù)實現(xiàn),依次調(diào)用即可。就是說,在進行面向過程 編程的時候,不需要考慮那么多,上來先定義一個...
摘要:在中,并沒有對抽象類和接口的支持。例如,當(dāng)對象需要對象的能力時,可以有選擇地把對象的構(gòu)造器的原型指向?qū)ο?,從而達到繼承的效果。本節(jié)內(nèi)容為設(shè)計模式與開發(fā)實踐第一章筆記。 動態(tài)類型語言 編程語言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語言與動態(tài)類型語言。 靜態(tài)類型語言在編譯時已確定變量類型,動態(tài)類型語言的變量類型要到程序運行時,待變量被賦值后,才具有某種類型。 而JavaScript是一門典型...
閱讀 3263·2021-11-23 09:51
閱讀 1059·2021-08-05 09:58
閱讀 696·2019-08-29 16:05
閱讀 1002·2019-08-28 18:17
閱讀 3059·2019-08-26 14:06
閱讀 2753·2019-08-26 12:20
閱讀 2195·2019-08-26 12:18
閱讀 3091·2019-08-26 11:56