JavaSE入門學習21:Java物件導向之介面(interface)(二)
一介面實現的多態
在上一篇博文:JavaSE入門學習20:Java物件導向之介面(interface)(一)中提到了介面的實現存在多態性,那麼
這一篇主要就要分析介面實現的多態。
執行個體一
Test.java源檔案代碼:
public class Test{public static void main(String[] args){//實現介面SingerSinger s1 = new Student("Amy");s1.sing();s1.sleep();s1.study();//編譯出錯//實現介面SingerSinger s2 = new Teacher("Jack");s2.sing();s2.sleep();s2.paint();//編譯出錯s2.eat();//編譯出錯s2.teach();//編譯出錯//實現介面PainterPainter p1 = (Painter)s2;p1.paint();p1.eat();p1.teach();//編譯出錯p1.sing();//編譯出錯p1.sleep();//編譯出錯}}//介面Singerinterface Singer{//抽象方法public void sing();public void sleep();}//介面Painterinterface Painter {//抽象方法public void paint();public void eat();}//學生類Student,繼承一個Singer介面class Student implements Singer{//私人成員變數private String name;//構造方法Student(String name){this.name = name;}public String getName(){return name;}//學生類專屬的study()方法public void study(){System.out.println("student is studying");}//重寫介面Singer中的sing()方法public void sing(){System.out.println("student is singing");}//重寫介面Singer中的sleep()方法public void sleep(){System.out.println("student is sleeping");}}//教師類Teacher,繼承兩個介面Singer和介面Painterclass Teacher implements Singer,Painter{//私人成員變數private String name;//建構函式Teacher(String name){this.name = name;}public String getName(){return name;}//Teacher類專屬的teach()方法public void teach(){System.out.println("teacher is teaching");}//重寫介面Singer的sing()方法public void sing(){System.out.println("teacher is singing");}//重寫介面Singer的sleep()方法public void sleep(){System.out.println("teacher is sleeping");}//重寫介面Painter的paint()方法public void paint(){System.out.println("teacher is painting");}//重寫介面Painter的eat()方法public void eat(){System.out.println("teacher is eating");}}
編譯過程報錯:
從上面報錯的資訊可以看出:在前面的敘述物件導向多態的時候就說過,引用多態和方法多態,以及多態中的引
用類型轉換,這些同樣在介面中都能實現,但是有區別的是,介面不能執行個體化,但是可以介面的引用可以指向繼承它
的子類的對象,當然調用的方法也是子類的重寫介面中的抽象方法的方法。具體的對象的多態性可以參考:JavaSE
入門學習18:Java物件導向之多態。
上面的編譯過程報錯的行數是7、13、14、15、21、22、23。這些報錯的類型都是找不到符號,這是因為引用類
型不一樣的原因,比如Singer介面的引用指向子類Student的對象s1,這個對象引用只能包含子類Student中重寫介面
Singer的兩個抽象方法,不能包含其它重寫Painter介面中的抽象方法以及子類Student本身專屬的方法,其它的類
似。為了避免這種編譯出錯,我們可以建立子類Student的對象和子類Teacher的對象。
執行個體二
改寫Test類中的代碼:
public class Test{public static void main(String[] args){//建立Student類的對象,實現介面SingerStudent s1 = new Student("Amy");s1.sing();s1.sleep();s1.study();//建立Teacher類的對象,實現介面Singer和介面PainterTeacher t1 = new Teacher("Jack");t1.sing();t1.sleep();t1.paint();t1.eat();t1.teach();}}
編譯運行結果:
二介面的用法(實際參考)(1)精簡程式結構,免除重複定義
比如,有兩個及上的的類擁有相同的方法,但是實現功能不一樣,就可以定義一個介面,將這個方法提煉出來,
在需要使用該方法的類中去實現,就免除了多個類定義系統方法的麻煩。
舉例:鳥類和昆蟲類都具有飛行的功能,這個功能是相同的,但是其它功能是不同的,在程式實現的過程中,就
可以定義一個介面,專門描述飛行。
是分別定義鳥類和昆蟲類,其都有飛行的方法,類圖為:
定義了介面,其類圖如下:
具體的代碼實現:
//介面FlyAnimalinterface FlyAnimal{ //抽象方法fly() void fly(); } //昆蟲類class Insect{ int legnum = 6; void oviposition(){};} //鳥類class Bird { int legnum = 2; void egg(){}; } //螞蟻類class Ant extends Insect implements FlyAnimal{ public void fly(){ System.out.println("Ant can fly"); } public void oviposition(){System.out.println("Ant can spawn"); }} //鴿子類class Pigeon extends Bird implements FlyAnimal{ public void fly(){ System.out.println("pigeon can fly"); } public void egg(){ System.out.println("pigeon can lay eggs "); } } public class Test{ public static void main(String args[]){ Ant a=new Ant(); a.fly(); a.oviposition(); System.out.println("Ant's legs are "+ a.legnum); System.out.println("\n"); Pigeon p= new Pigeon(); p.fly(); p.egg(); System.out.println("Pigeon's legs are "+ p.legnum); } }
編譯運行結果:
(2)拓展程式功能,應對需求變化
假設一個學校接待方面的程式,招待不同身份的人的食宿問題,其對應規則如下:
理論上,當然可以對每個不同身份的人各定義一個對應的類,並實現各自的方法,但是觀察這寫類,可以歸納出
其有一個共同的模板,即“人”的“食、宿”問題。這時候,就可以發揮介面的功能了。
具體實現代碼如下:
interface Person{ void eat(); void sleep(); } class Student implements Person{ public void eat(){ System.out.println("學生去食堂吃飯!"); } public void sleep(){ System.out.println("學生回寢室睡覺!"); } } class Teacher implements Person{ public void eat(){ System.out.println("教師去教工餐廳吃飯!"); } public void sleep(){ System.out.println("教師回學校公寓睡覺!"); } } class Parents implements Person{ public void eat(){ System.out.println("家長去招待所飯館吃飯!"); } public void sleep(){ System.out.println("家長回招待所睡覺!"); } } public class Test{ public static void main(String[] args){ Person p1 = new Student(); p.eat(); p.sleep(); Person p2 = new Teacher(); p.eat(); p.sleep(); Person p3 = new Parents(); p.eat(); p.sleep(); } }
運行結果:
現在需要添加一些功能,即現在需要添加“外賓、上級領導”兩類角色,並且以後工具需要還要添加相應的身份角
色的人進來,此時,只需要根據需要添加“外賓”類、“領導”類,而主類仍然可以拿來就用,無需進行更多的修改。此
時就可以顯示出介面的作用了。
我們列表現在更新為:
在上面的程式中添加如下兩個類即可:
class Foreign implements Person{ public void eat(){ System.out.println("外賓去酒店吃飯!"); } public void sleep(){ System.out.println("外賓回酒店睡覺!"); } } class Leader implements Person{ public void eat(){ System.out.println("領導去賓館吃飯!"); } public void sleep(){ System.out.println("領導回賓館睡覺!"); } }
我們在主方法中添加的代碼為:
Person p4 = new Foreign(); p4.eat(); p4.sleep(); Person p5 = new Leader(); p5.eat(); p5.sleep();
運行結果:
總結