13.1抽象類
13.1.1?概念
當父類的一些方法不能確定時,可以用abstract關鍵字來修飾該方法,稱為抽象方法,用abstract來修飾該類,稱為抽象類。
13.1.2?抽象類-深入討論
抽象類是java中一個比較重要的類:
1、用abstract關鍵字來修飾一個類時,這個類就叫抽象類;
2、用abstract關鍵字來修飾一個方法時,這個方法就叫抽象方法;
3、抽象方法在編程中用的不是很多,但是在公司筆試時考的較多。
13.1.3?抽象類-注意事項
1、抽象類不能實例化;
2、抽象類不一定要包含abstract方法;
3、一旦包含有abstract方法,則這個類必須聲明為abstract類;
4、抽象方法不能有主體。例如?abstract?void?cry();??不能加{}
13.2?接口
13.2.1?概念
接口就是給出一些沒有內容的方法,封裝到一起,到某個類要使用的時候,再根據具體情況把這些方法寫出來。語法:
class?類名?implements?接口
{
方法;
變量;
}
小結:接口是更加抽象的抽象的類,抽象類里的方法可以有方法體,但接口里的所有方法都沒有方法體。接口體現了程序設計的多態和高內聚低耦合的設計思想。
13.2.2?注意事項
1、接口不能被實例化;
2、接口中所有的方法都不能有主體;例如?void?cry();?后不能有{}
3、一個類可以實現多個接口;
4、接口中可以有變量(但是變量不能用private和protected修飾),注意:
a.?接口中的變量,本質上都是static的,而且是final,不管你加不加static修飾;
b.?在java開發中,經常把常用的變量,定義在接口中,作為全局變量使用。
訪問形式:?接口名.變量名
5、一個接口不能繼承其它的類,但是可以繼承別的接口。
13.3?實現接口?vs?繼承類
1、Java的繼承是單繼承,也就是一個類最多只能有一個父類,這種單繼承的機制可以保證類的純潔性,比c++中的多繼承機制簡潔。但是不可否認,對子類功能的擴展有一定影響。所以我們認為:實現接口可以看作是對繼承的一種補充。
2、還有一點,繼承是層級式的,不太靈活。這種結構修改某個類就會打破這種繼承的平衡,而接口就沒有這樣的麻煩,因為它只針對實現接口的類才起作用。所以:實現接口可以在不打破集成關系的前提下,對某個類功能進行擴展,非常靈活。
13.4?綁定
將一個方法調用同這個方法所屬的主體(也就是對象或類)關聯起來叫做綁定,分前期綁定和后期綁定兩種。
1、前期綁定:在程序運行之前進行綁定,由編譯器和連接程序實現,又叫做靜態綁定,比如static方法和final方法(注意:這里也包括private方法,因為它是隱式final的);
2、后期綁定:在運行時根據對象的類型進行綁定,由方法調用機制實現,因此又叫做動態綁定,或者運行時綁定,除了前期綁定外的所有方法都屬于后期綁定。
多態就是在后期綁定這種機制上實現的。
13.5?接口多態優點
繼承是多態得以實現的基礎。
從字面上理解,多態就是一種類型(如?都是Car類型)表現出多種形態(寶馬名字是BMW,售價是300000;奇瑞名字是CheryQQ,售價是20000)。
多態給我們帶來的好處是消除了類的耦合關系,使程序更容易擴展。
比如在汽車銷售的例子中,新增加一種類型汽車的銷售,只需要讓新定義的類實現Car并實現它的所有方法,而無需對原有代碼做任何修改,CarShop類的sellCar(Car?car)方法就可以處理新的車型了。
?
抽象類的演示代碼如下:
?
1 /**日期:2016-03-04 2 * 功能:抽象類的演示 3 */ 4 public class Practice4 5 { 6 public static void main(String []args) 7 { 8 //Animal an=new Animal(); //抽象類不能實例化 9 Cat1 cat=new Cat1(); 10 cat.cry(); 11 } 12 } 13 14 abstract class Animal1 //這就是一個抽象類 15 { 16 String name; 17 int age; 18 abstract public void cry();//抽象類中也可以沒有抽象類,這時cry就變成了Cat類自己的成員方法 19 public void eat() //抽象類中也可以有實現的類 20 { 21 22 } 23 } 24 25 class Cat1 26 { 27 //當一個類繼承的父類是抽象類的話,需要我們把父類中的抽象方法都實現 28 29 public void cry() 30 { 31 System.out.println("喵喵叫!"); 32 } 33 }
?
運行結果如下:
1 喵喵叫!
?
?接口演示代碼如下:
1 /**日期:2016-03-05 2 * 功能:接口的演示 3 */ 4 public class Practice1 5 { 6 public static void main(String []args) 7 { 8 Computer computer1=new Computer(); 9 computer1.useUsb(new Camera()); //體現了多態 10 computer1.useUsb(new Phone()); //體現了多態 11 computer1.insertEarPhone(new Phone()); //體現了多態 12 System.out.println(Usb.wrongMessage); //直接調用接口中聲明的變量 13 } 14 } 15 class Computer 16 { 17 public void useUsb(Usb usb) //體現了多態 18 { 19 usb.start(); 20 usb.stop(); 21 } 22 public void insertEarPhone(Earphone earphone) 23 { 24 earphone.notice(); 25 earphone.noticeSim(); 26 } 27 } 28 interface Usb //定義接口 29 { 30 //接口中聲明的變量為static的和final的(即必須初始化),可作為全局變量 31 String wrongMessage="404 not found!"; 32 public void start(); 33 public void stop(); 34 } 35 36 interface Simcard 37 { 38 public void noticeSim(); 39 } 40 41 interface Earphone extends Simcard //一個接口不能繼承其它的類,但是可以繼承別的接口 42 { 43 public void notice(); 44 } 45 46 //編寫相機類,并實現Usb接口 47 //重要原則:當一個類實現了一個接口,就要求該類將這個接口的所有方法統統實現 48 class Camera implements Usb 49 { 50 public void start() 51 { 52 System.out.println("相機開始工作!"); 53 } 54 public void stop() 55 { 56 System.out.println("相機停止工作!"); 57 } 58 } 59 60 class Phone implements Usb,Earphone //一個類可以實現多個接口 61 { 62 public void start() 63 { 64 System.out.println("手機開始工作!"); 65 } 66 public void stop() 67 { 68 System.out.println("手機停止工作!"); 69 } 70 public void notice() 71 { 72 System.out.println("耳機插入了!"); 73 } 74 //Earphone繼承了Simcard接口,所以必須將Simcard接口里的所有方法也實現 75 public void noticeSim() 76 { 77 System.out.println("SIM卡插入了!"); 78 } 79 }
運行結果如下:
1 相機開始工作! 2 相機停止工作! 3 手機開始工作! 4 手機停止工作! 5 耳機插入了! 6 SIM卡插入了! 7 404 not found!
?
接口擴展靈活性演示代碼如下:
1 /**日期:2016-03-05 2 * 功能:接口擴展靈活性的演示 3 * 說明:增加一種銷售車輛時,只需要增加下面演示的代碼A和代碼B就可以了,無需修改其它代碼,很方便 4 */ 5 public class Practice 6 { 7 public static void main(String []args) 8 { 9 CarShop carshop1=new CarShop(); 10 carshop1.sellCar(new BMW()); 11 carshop1.sellCar(new CheryQQ()); 12 //carshop1.sellCar(new Audy()); //代碼A:增加銷售車輛時,增加該行代碼 13 } 14 } 15 class CarShop 16 { 17 private int income=0; 18 public void sellCar(Car car) 19 { 20 System.out.println("賣出了一輛"+car.getName()); 21 income+=car.getPrice(); 22 System.out.println("收入"+income); 23 } 24 } 25 26 interface Car 27 { 28 public String getName(); 29 public int getPrice(); 30 } 31 32 class BMW implements Car 33 { 34 35 @Override 36 public String getName() { 37 // TODO Auto-generated method stub 38 return "BMW"; 39 } 40 41 @Override 42 public int getPrice() { 43 // TODO Auto-generated method stub 44 return 300000; 45 } 46 47 } 48 49 class CheryQQ implements Car 50 { 51 52 @Override 53 public String getName() { 54 // TODO Auto-generated method stub 55 return "CheryQQ"; 56 } 57 58 @Override 59 public int getPrice() { 60 // TODO Auto-generated method stub 61 return 20000; 62 } 63 64 } 65 66 //代碼B:增加銷售車輛時,增加該段代碼 67 /*class Audy implements Car 68 { 69 70 @Override 71 public String getName() { 72 // TODO Auto-generated method stub 73 return "Audy"; 74 } 75 76 @Override 77 public int getPrice() { 78 // TODO Auto-generated method stub 79 return 200000; 80 } 81 82 }*/
運行結果如下:
1 賣出了一輛BMW 2 收入300000 3 賣出了一輛CheryQQ 4 收入320000
?