第3天 面向對象java
今日內容介紹
接口
多態
筆記本案例
今日學習目標
寫出定義接口的格式
寫出實現接口的格式
說出接口中成員的特色
接口和抽象類的區別
可以說出使用多態的前提條件
理解多態的向上轉型
理解多態的向下轉型
可以完成筆記本電腦案例(方法參數爲接口)學習
第1章 接口優化
1.1 接口概念設計
類:具備相同屬性和功能的事物集合code
接口是功能的集合,一樣可看作是一種數據類型,是比抽象類更爲抽象的」類」。對象
接口只描述所應該具有的方法,並無具體實現,具體的實現由接口的實現類(至關於接口的子類)來完成。這樣將功能的定義與實現分離,優化了程序設計。
請記住:一切事物均有功能,即一切事物均有接口。繼承
1.2 接口的定義接口
與定義類的class不一樣,接口定義時須要使用interface關鍵字。
定義接口所在的仍爲.java文件,雖然聲明時使用的爲interface關鍵字的編譯後仍然會產生.class文件。這點可讓咱們將接口看作是一種只包含了功能聲明的特殊類。
定義格式:
public interface 接口名 {
抽象方法1;
抽象方法2;
抽象方法3;
}
使用interface代替了原來的class,其餘步驟與定義類相同:
接口中的方法均爲公共訪問的抽象方法
接口中沒法定義普通的成員變量編譯
1.3 類實現接口程序設計
類與接口的關係爲實現關係,即類實現接口。實現的動做相似繼承,只是關鍵字不一樣,實現使用implements。
其餘類(實現類)實現接口後,就至關於聲明:」我應該具有這個接口中的功能」。實現類仍然須要重寫方法以實現具體的功能。
格式:
class 實現類 implements 接口 {
重寫接口中全部方法
}
在類實現接口後,該類就會將接口中的抽象方法繼承過來,此時該類須要重寫該抽象方法,完成具體的邏輯。
接口中定義功能,當須要具備該功能時,可讓類實現該接口,只聲明瞭應該具有該方法,是功能的聲明。
在具體實現類中重寫方法,實現功能,是方法的具體實現。
因而,經過以上兩個動做將功能的聲明與實現便分開了。(此時請從新思考:類是現實事物的描述,接口是功能的集合。)
1.4 接口中成員的特色
一、接口中能夠定義成員變量,可是變量必須有固定的修飾符修飾,public static final 因此接口中的變量也稱之爲常量,其值不能改變。後面咱們會講解static與final關鍵字
二、接口中能夠定義方法,方法也有固定的修飾符,public abstract
三、接口不能夠建立對象。
四、實現類必須覆蓋掉接口中全部的抽象方法後,實現類才能夠實例化。不然實現類是一個抽象類。
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 接口和抽象類的區別*
明白了接口思想和接口的用法後,接口和抽象類的區別是什麼呢?接口在生活體現也基本掌握,那在程序中接口是如何體現的呢?
經過實例進行分析和代碼演示抽象類和接口的用法。
一、舉例:
犬:
行爲:
吼叫; 吃飯;
緝毒犬:
行爲:
吼叫; 吃飯; 緝毒;
二、思考:
因爲犬分爲不少種類,他們吼叫和吃飯的方式不同,在描述的時候不能具體化,也就是吼叫和吃飯的行爲不能明確。當描述行爲時,行爲的具體動做不能明確,這時,能夠將這個行爲寫爲抽象行爲,那麼這個類也就是抽象類。
但是當緝毒犬有其餘額外功能時,而這個功能並不在這個事物的體系中。這時可讓緝毒犬具有犬科自身特色的同時也有其餘額外功能,能夠將這個額外功能定義接口中。
以下代碼演示:
interface 緝毒{ public abstract void 緝毒(); } //定義犬科的這個提醒的共性功能 abstract class 犬科{ public abstract void 吃飯(); public abstract void 吼叫(); } // 緝毒犬屬於犬科一種,讓其繼承犬科,獲取的犬科的特性, //因爲緝毒犬具備緝毒功能,那麼它只要實現緝毒接口便可,這樣即保證緝毒犬具有犬科的特性,也擁有了緝毒的功能 class 緝毒犬 extends 犬科 implements 緝毒{ public void 緝毒() { } void 吃飯() { } void 吼叫() { } } class 緝毒豬 implements 緝毒{ public void 緝毒() { } }
三、經過上面的例子總結接口和抽象類的區別:
相同點:
都位於繼承的頂端,用於被其餘類實現或繼承;
都不能直接實例化對象;
均可以包含抽象方法,其子類都必須覆寫這些抽象方法;
區別:
抽象類爲部分方法提供實現,避免子類重複實現這些方法,提升代碼重用性;
接口只能包含抽象方法;
一個類只能繼承一個直接父類(多是抽象類),卻能夠實現多個接口;(接口彌補了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(); } }