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