今日內容介紹
一、接口
二、多態java
* A:接口的概念 接口是功能的集合,一樣可看作是一種數據類型,是比抽象類更爲抽象的」類」。 接口只描述所應該具有的方法,並無具體實現,具體的實現由接口的 實現類(至關於接口的子類)來完成。這樣將功能的定義與實現分離,優化了程序設計。 請記住:一切事物均有功能,即一切事物均有接口。
與定義類的class不一樣,接口定義時須要使用interface關鍵字。 定義接口所在的仍爲.java文件,雖然聲明時使用的爲interface關鍵字的編譯後 仍然會產生.class文件。這點可讓咱們將接口看作是一種只包含了功能聲明的特殊類。
public interface 接口名 { 抽象方法1; 抽象方法2; 抽象方法3; }
使用interface代替了原來的class,其餘步驟與定義類相同: 接口中的方法均爲公共訪問的抽象方法 接口中沒法定義普通的成員變量
類與接口的關係爲實現關係,即類實現接口。實現的動做相似繼承,只是關鍵字不一樣,實現使用implements。 其餘類(實現類)實現接口後,就至關於聲明:」我應該具有這個接口中的功能」。實現類仍然須要重寫方法以實現具體的功能。
class 類 implements 接口 { 重寫接口中方法 }
在類實現接口後,該類就會將接口中的抽象方法繼承過來,此時該類須要重寫該抽象方法,完成具體的邏輯。 接口中定義功能,當須要具備該功能時,可讓類實現該接口,只聲明瞭應該具有該方法,是功能的聲明。 在具體實現類中重寫方法,實現功能,是方法的具體實現。
interface Demo { ///定義一個名稱爲Demo的接口。 public static final int NUM = 3;// NUM的值不能改變 }
A: 成員方法特色學習
interface Demo { ///定義一個名稱爲Demo的接口。 public abstract void show1(); public abstract void show2(); } //定義子類去覆蓋接口中的方法。類與接口之間的關係是 實現。經過 關鍵字 implements class DemoImpl implements Demo { //子類實現Demo接口。 //重寫接口中的方法。 public void show1(){} public void show2(){} }
A: 接口的實現類 一個類若是實現類接口,有兩種操做方法: 第一:實現類是非抽象類,就須要重寫接口中全部的抽象方法. 第二:實現類也聲明爲抽象類,那麼實現類能夠不重寫接口中的抽象方法。
A:接口的多實現
瞭解了接口的特色後,那麼想一想爲何要定義接口,使用抽象類描述也沒有問題,接口到底有啥用呢?
接口最重要的體現:解決多繼承的弊端。將多繼承這種機制在java中經過多實現完成了。測試
C :案例演示優化
interface Fu2{ void show2(); } class Zi implements Fu1,Fu2 { // 多實現。同時實現多個接口。 public void show1(){} public void show2(){} }
class Fu { public void show(){} } interface Inter { pulbic abstract void show1(); } class Zi extends Fu implements Inter { public void show1() { } } 接口的出現避免了單繼承的侷限性。父類中定義的事物的基本功能。接口中定義的事物的擴展功能。
B 代碼演示
interface Fu1{
void show();
}
interface Fu2{
void show1();
}
interface Fu3{
void show2();
}
interface Zi extends Fu1,Fu2,Fu3{
void show3();
}設計
在開發中若是多個接口中存在相同方法,這時如有個類實現了這些接口,那麼就要實現接 口中的方法,因爲接口中的方法是抽象方法,子類實現後也不會發生調用的不肯定性。
三、接口的出現下降了耦合性,即設備與設備之間實現瞭解耦。code
接口的出現方便後期使用和維護,一方是在使用接口(如電腦),一方在實現接口(插在插口上的設備)。例如:筆記本使用這個規則(接口),電腦外圍設備實現這個規則(接口)。對象
interface 緝毒{ public abstract void 緝毒(); } //定義犬科的這個提醒的共性功能 abstract class 犬科{ public abstract void 吃飯(); public abstract void 吼叫(); } // 緝毒犬屬於犬科一種,讓其繼承犬科,獲取的犬科的特性, //因爲緝毒犬具備緝毒功能,那麼它只要實現緝毒接口便可,這樣即保證緝毒犬具有犬科的特性,也擁有了緝毒的功能 class 緝毒犬 extends 犬科 implements 緝毒{ public void 緝毒() { } void 吃飯() { } void 吼叫() { } } class 緝毒豬 implements 緝毒{ public void 緝毒() { } }
相同點: 都位於繼承的頂端,用於被其餘類實現或繼承; 都不能直接實例化對象; 都包含抽象方法,其子類都必須覆寫這些抽象方法; 區別: 抽象類爲部分方法提供實現,避免子類重複實現這些方法,提升代碼重用性;接口只能包含抽象方法; 一個類只能繼承一個直接父類(多是抽象類),卻能夠實現多個接口;(接口彌補了Java的單繼承) 抽象類是這個事物中應該具有的你內容, 繼承體系是一種 is..a關係 接口是這個事物中的額外內容,繼承體系是一種 like..a關係 兩者的選用: 優先選用接口,儘可能少用抽象類; 須要定義子類的行爲,又要爲子類提供共性功能時才選用抽象類;
多態是繼封裝、繼承以後,面向對象的第三大特性。繼承
現實事物常常會體現出多種形態,如學生,學生是人的一種,則一個具體的同窗張三既是學生也是人,即出現兩種形態。接口
Java做爲面向對象的語言,一樣能夠描述一個事物的多種形態。如Student類繼承了Person類,一個Student的對象便既是Student,又是Person。遊戲
Java中多態的代碼體如今一個子類對象(實現類對象)既能夠給這個子類(實現類對象)引用變量賦值,又能夠給這個子類(實現類對象)的父類(接口)變量賦值。
如Student類能夠爲Person類的子類。那麼一個Student對象既能夠賦值給一個Student類型的引用,也能夠賦值給一個Person類型的引用。
最終多態體現爲父類引用變量能夠指向子類對象。
多態的前提是必須有子父類關係或者類實現接口關係,不然沒法完成多態。
在使用多態後的父類引用變量調用方法時,會調用子類重寫後的方法。
A:多態的定義格式:
父類 變量名 = new 子類(); 舉例: class Fu {} class Zi extends Fu {} //類的多態使用 Fu f = new Zi();
抽象類 變量名 = new 抽象類子類(); 舉例: abstract class Fu { public abstract void method(); } class Zi extends Fu { public void method(){ System.out.println(「重寫父類抽象方法」); } } //類的多態使用 Fu fu= new Zi();
接口 變量名 = new 接口實現類(); 如: interface Fu { public abstract void method(); } class Zi implements Fu { public void method(){ System.out.println(「重寫接口抽象方法」); } } //接口的多態使用 Fu fu = new Zi();
同一個父類的方法會被不一樣的子類重寫。在調用方法時,調用的爲各個子類重寫後的方法。 如 Person p1 = new Student(); Person p2 = new Teacher(); p1.work(); //p1會調用Student類中重寫的work方法 p2.work(); //p2會調用Teacher類中重寫的work方法 當變量名指向不一樣的子類對象時,因爲每一個子類重寫父類方法的內容不一樣,因此會調用不一樣的方法。
class Fu { int num = 4; } class Zi extends Fu { int num = 5; } class Demo { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num); Zi z = new Zi(); System.out.println(z.num); } }
當子父類中出現同名的成員變量時,多態調用該變量時:
編譯時期:參考的是引用型變量所屬的類中是否有被調用的成員變量。沒有,編譯失敗。
運行時期:也是調用引用型變量所屬的類中的成員變量。
簡單記:編譯和運行都參考等號的左邊。編譯運行看左邊。
class Fu { int num = 4; void show() { System.out.println("Fu show num"); } } class Zi extends Fu { int num = 5; void show() { System.out.println("Zi show num"); } } class Demo { public static void main(String[] args) { Fu f = new Zi(); f.show(); } }
編譯時期:參考引用變量所屬的類,若是沒有類中沒有調用的方法,編譯失敗。
運行時期:參考引用變量所指的對象所屬的類,並運行對象所屬類中的成員方法。
簡而言之:編譯看左邊,運行看右邊。
A: 做用
能夠經過instanceof關鍵字來判斷某個對象是否屬於某種數據類型。如學生的對象屬於學生類,學生的對象也屬於人類
格式:
boolean b = 對象 instanceof 數據類型;
Person p1 = new Student(); // 前提條件,學生類已經繼承了人類 boolean flag = p1 instanceof Student; //flag結果爲true boolean flag2 = p2 instanceof Teacher; //flag結果爲false
* A: 多態的轉型分爲向上轉型與向下轉型兩種: * B: 向上轉型:當有子類對象賦值給一個父類引用時,即是向上轉型,多態自己就是向上轉型的過程。 * 使用格式: 父類類型 變量名 = new 子類類型(); 如:Person p = new Student();
* A: 向下轉型:一個已經向上轉型的子類對象可使用強制類型轉換的格式,將父類引用轉爲子 * 類引用,這個過程是向下轉型。若是是直接建立父類對象,是沒法向下轉型的! * 使用格式: 子類類型 變量名 = (子類類型) 父類類型的變量; 如:Student stu = (Student) p; //變量p 實際上指向Student對象
* A: 多態的好處和弊端 * 當父類的引用指向子類對象時,就發生了向上轉型,即把子類類型對象轉成了父類類型。 向上轉型的好處是隱藏了子類類型,提升了代碼的擴展性。 * 但向上轉型也有弊端,只能使用父類共性的內容,而沒法使用子類特有功能,功能有限制。 * B: 看以下代碼 //描述動物類,並抽取共性eat方法 abstract class Animal { abstract void eat(); } // 描述狗類,繼承動物類,重寫eat方法,增長lookHome方法 class Dog extends Animal { void eat() { System.out.println("啃骨頭"); } void lookHome() { System.out.println("看家"); } } // 描述貓類,繼承動物類,重寫eat方法,增長catchMouse方法 class Cat extends Animal { void eat() { System.out.println("吃魚"); } void catchMouse() { System.out.println("抓老鼠"); } } public class Test { public static void main(String[] args) { Animal a = new Dog(); //多態形式,建立一個狗對象 a.eat(); // 調用對象中的方法,會執行狗類中的eat方法 // a.lookHome();//使用Dog類特有的方法,須要向下轉型,不能直接使用 // 爲了使用狗類的lookHome方法,須要向下轉型 // 向下轉型過程當中,可能會發生類型轉換的錯誤,即ClassCastException異常 // 那麼,在轉以前須要作健壯性判斷 if( !a instanceof Dog){ // 判斷當前對象是不是Dog類型 System.out.println("類型不匹配,不能轉換"); return; } Dog d = (Dog) a; //向下轉型 d.lookHome();//調用狗類的lookHome方法 } } * C 多態總結: 何時使用向上轉型: 當不須要面對子類類型時,經過提升擴展性,或者使用父類的功能就能完成相應的操做, 這時就可使用向上轉型。 如:Animal a = new Dog(); a.eat(); 何時使用向下轉型 當要使用子類特有功能時,就須要使用向下轉型。 如:Dog d = (Dog) a; //向下轉型 d.lookHome();//調用狗類的lookHome方法 向下轉型的好處:可使用子類特有功能。 弊端是:須要面對具體的子類對象;在向下轉型時容易發生 ClassCastException類型轉換異常。在轉換以前必須作類型判斷。 如:if( !a instanceof Dog){…}
* A: 畢老師和畢姥爺的故事 * 案例: /* 描述畢老師和畢姥爺, 畢老師擁有講課和看電影功能 畢姥爺擁有講課和釣魚功能 */ class 畢姥爺 { void 講課() { System.out.println("政治"); } void 釣魚() { System.out.println("釣魚"); } } // 畢老師繼承了畢姥爺,就有擁有了畢姥爺的講課和釣魚的功能, // 但畢老師和畢姥爺的講課內容不同,所以畢老師要覆蓋畢姥爺的講課功能 class 畢老師 extends 畢姥爺 { void 講課() { System.out.println("Java"); } void 看電影() { System.out.println("看電影"); } } public class Test { public static void main(String[] args) { // 多態形式 畢姥爺 a = new 畢老師(); // 向上轉型 a.講課(); // 這裏表象是畢姥爺,其實真正講課的仍然是畢老師,所以調用的也是畢老師的講課功能 a.釣魚(); // 這裏表象是畢姥爺,但對象實際上是畢老師,而畢老師繼承了畢姥爺,即畢老師也具備釣魚功能 // 當要調用畢老師特有的看電影功能時,就必須進行類型轉換 畢老師 b = (畢老師) a; // 向下轉型 b.看電影(); }
* A: 代碼實現 定義鼠標、鍵盤,筆記本三者之間應該遵照的規則 interface USB { void open();// 開啓功能 void close();// 關閉功能 } 鼠標實現USB規則 class Mouse implements USB { public void open() { System.out.println("鼠標開啓"); } public void close() { System.out.println("鼠標關閉"); } } 鍵盤實現USB規則 class KeyBoard implements USB { public void open() { System.out.println("鍵盤開啓"); } public void close() { System.out.println("鍵盤關閉"); } } 定義筆記本 class NoteBook { // 筆記本開啓運行功能 public void run() { System.out.println("筆記本運行"); } // 筆記本使用usb設備,這時當筆記本對象調用這個功能時,必須給其傳遞一個符合USB規則的USB設備 public void useUSB(USB usb) { // 判斷是否有USB設備 if (usb != null) { usb.open(); usb.close(); } } public void shutDown() { System.out.println("筆記本關閉"); } } public class Test { public static void 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(); } }
一、多態是什麼,多態的前提條件是什麼?
二、多態中成員訪問的特色分別是什麼?
成員變量
成員方法(非靜態方法)
靜態方法
三、什麼是接口,它的特色是什麼?
四、接口的成員特色有哪些?
五、抽象類和接口的區別是什麼?
6:定義一個父類Animal eat方法 , 定義兩個子類 Dog 特有方法keepHome , Cat 特有方法 catchMouse ;而且 重寫eat方法
測試類中寫一個方法,參數列表有一個參數Animla類型,
要求: 調用該方法分別傳遞Dog對象 和Cat 對象, 使用instanceof進行將轉後調用eat,和他們的特有方法
7.測試: 若是一個方法的返回值類型是父類,那麼可否返回一個子類對象.(該父類無論是類,抽象類仍是接口)
8.現有兩種 OldPhone NewPhone; 兩個類都有call() sendMessage() 方法(考慮向上抽取一個父類);
已知接口IPlay中有一個方法 playGame(),NewPhone添加玩遊戲的功能; 要求: 分別測試OldPhone和NewPhone的兩個方法,再測試新手機palyGame()的方法.
9 .(完成下面的汽車案例)
描述:汽車都具備跑的功能,普通的奧迪車也不例外,可是高端的奧迪車除了具備跑的功能外,還具備自動泊車和無人駕駛的功能! 需求:定義普通奧迪車,高端奧迪車,實現描述中的功能並測試