農資銷售網站建設方案sem百度競價推廣
由來
當我們聲明一個幾何圖形類:圓、矩形、三角形類等,發(fā)現這些類都有共同特征:求面積、求周長、獲取圖形詳細信息。那么這些共同特征應該抽取到一個公共父類中。但是這些方法在父類中又無法給出具體的實現,而是應該交給子類各自具體實現。那么父類在聲明這些方法時,就只有方法簽名,沒有方法體,我們把沒有方法體的方法稱為抽象方法。Java語法規(guī)定,包含抽象方法的類必須是抽象類。
抽象類的語法格式
特點:沒有方法體且被abstract修飾的方法
抽象方法的語法格式 ?
特點:抽象方法沒有方法體 ,且被abstract關鍵字修飾
注意事項
關于抽象類的使用,以下為語法上要注意的細節(jié),雖然條目較多,但若理解了抽象的本質,無需死記硬背。
-
抽象類不能創(chuàng)建對象,如果創(chuàng)建,編譯無法通過而報錯。只能創(chuàng)建其非抽象子類的對象。
理解:假設創(chuàng)建了抽象類的對象,調用抽象的方法,而抽象方法沒有具體的方法體,沒有意義。
-
抽象類中,也有構造方法,是供子類創(chuàng)建對象時,初始化父類成員變量使用的。
理解:子類的構造方法中,有默認的super()或手動的super(實參列表),需要訪問父類構造方法。
-
抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
理解:未包含抽象方法的抽象類,目的就是不想讓調用者創(chuàng)建該類對象,通常用于某些特殊的類結構設計。
-
抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報錯。除非該子類也是抽象類。
理解:假設不重寫所有抽象方法,則類中可能包含抽象方法。那么創(chuàng)建對象后,調用抽象的方法,沒有意義。
代碼示例
定義抽象類
//抽象類
public abstract class Anima {//類中成員變量private String name;//抽象類中,也有構造方法,是供子類創(chuàng)建對象時,初始化父類成員變量使用的。public Anima(String name) {this.name = name;}public Anima() {}//成員方法public String getName() {return name;}public void setName(String name) {this.name = name;}//抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類。public abstract void eat();
}
?定義實現類
public class Dog extends Anima{public Dog(String name) {super(name);}public Dog() {}@Override//抽象類的子類,必須重寫抽象父類中所有的抽象方法,除非該子類也是抽象類。 public void eat() {System.out.println("狗狗吃骨頭");}
}
定義測試類
public class Test {public static void main(String[] args) {// Anima anima = new Anima();抽象類不能創(chuàng)建對象//只能創(chuàng)建其非抽象子類的對象。Dog dog = new Dog("大黃");dog.eat();//狗狗吃骨頭System.out.println(dog.getName());//大黃}
}
接口
由來
電腦邊上提供了USB插槽,這個插槽遵循了USB的規(guī)范,只要其他設備也是遵循USB規(guī)范的,那么就可以互聯,并正常通信。至于這個電腦、以及其他設備是哪個廠家制造的,內部是如何實現的,我們都無需關心。
這種設計是將規(guī)范和實現分離,這也正是Java接口的好處。Java的軟件系統會有很多模塊組成,那么各個模塊之間也應該采用這種面相接口的低耦合,為系統提供更好的可擴展性和可維護性。
接口就是規(guī)范,定義的是一組規(guī)則,體現了現實世界中“如果你是/要...則必須能...”的思想。繼承是一個"是不是"的is-a關系,而接口實現則是 "能不能"的has-a關系。理解:接口是從多個相似類中抽象出來的規(guī)范,不需要提供具體實現
- 例如:你能不能用USB進行連接,或是否具備USB通信功能,就看你是否遵循USB接口規(guī)范
- 例如:Java程序是否能夠連接使用某種數據庫產品,那么要看該數據庫產品有沒有實現Java設計的JDBC規(guī)范
為什么接口中只能聲明公共的靜態(tài)的常量?
- 因為接口是標準規(guī)范,在規(guī)范中需要聲明一些底線邊界值,當實現者在實現這些規(guī)范時,不能去隨意修改和觸碰這些底線,否則就有“危險”。
接口的定義,它與定義類方式相似,但是使用 interface關鍵字。它也會被編譯成.class文件,但一定要明確接口并不是類,而是另外一種引用數據類型。
接口中可以聲明什么?
在JDK8之前,接口中只允許出現:
- 公共的靜態(tài)的常量:其中public static final可以省略。
- 公共的抽象的方法:其中public abstract可以省略
//定義接口
public interface Fly {//公共的靜態(tài)的常量:其中public static final可以省略String name = "示例代碼";// 公共的抽象的方法:其中public abstract可以省略void fly();
}
在JDK1.8時,接口中允許聲明默認方法和靜態(tài)方法:
- 公共的默認的方法:其中public 可以省略,建議保留,但是default不能省略。
- 我們要在已有的老版接口中提供新方法時,如果添加抽象方法,就會涉及到原來使用這些接口的類就會有問題,那么為了保持與舊版本代碼的兼容性,只能允許在接口中定義默認方法實現。比如:Java8中對Collection、List、Comparator等接口提供了豐富的默認方法。
- 當我們接口的某個抽象方法,在很多實現類中的實現代碼是一樣的,此時將這個抽象方法設計為默認方法更為合適,那么實現類就可以選擇重寫,也可以選擇不重寫。
- 重寫時,default單詞就不要再寫了,它只用于在接口中表示默認方法,到類中就沒有默認方法的概念了
- 公共的靜態(tài)的方法:其中public 可以省略,建議保留,但是static不能省略。之前的標準類庫設計中,有很多Collection/Colletions或者Path/Paths這樣成對的接口和類,后面的類中都是靜態(tài)方法,而這些靜態(tài)方法都是為前面的接口服務的,那么這樣設計一對API,不如把靜態(tài)方法直接定義到接口中使用和維護更方便
//定義接口
public interface Fly {//默認方法public default void start(){System.out.println("默認方法");}//靜態(tài)方法public static void show(){System.out.println("靜態(tài)方法");}
}
在JDK1.9時,接口又增加了:
- 私有方法:因為有了默認方法和靜態(tài)方法這樣具有具體實現的方法,那么就可能出現多個方法由共同的代碼可以抽取,而這些共同的代碼抽取出來的方法又只希望在接口內部使用,所以就增加了私有方法。
除此之外,接口中不能有其他成員,沒有構造器,沒有初始化塊,因為接口中沒有成員變量需要初始化。
接口的聲明格式
實現接口
接口的使用,它不能創(chuàng)建對象,但是可以被實現(implements,類似于被繼承)。類與接口的關系為實現關系,即類實現接口,該類可以稱為接口的實現類,也習慣稱為接口的子類(嚴格來說,實現類不是子類)。實現的動作類似繼承,格式相仿,只是關鍵字不同,實現使用 implements關鍵字。
注意:實現類不能繼承接口中的靜態(tài)方法和私有方法
實現接口語法格式
如何調用對應的方法
-
對于接口的靜態(tài)方法,直接使用“接口名.”進行調用即可。也只能使用“接口名."進行調用,不能通過實現類的對象進行調用
-
對于接口的抽象方法、默認方法,只能通過實現類對象才可以調用。接口不能直接創(chuàng)建對象,只能創(chuàng)建實現類的對象
代碼示例
定義接口
//定義接口
public interface LiveAble {// 定義抽象方法public abstract void eat();public abstract void breathe();//定義默認方法public default void sleep(){System.out.println("靜止不動");}//定義靜態(tài)方法public static void drink(){System.out.println("喝水");}
}
定義實現類Animal
public class Animal implements LiveAble{//重寫/實現接口的抽象方法@Overridepublic void eat() {System.out.println("吃東西");}//重寫/實現接口的抽象方法@Overridepublic void breathe(){System.out.println("吸入氧氣呼出二氧化碳");}//重寫接口的默認方法@Overridepublic void sleep() {System.out.println("閉上眼睛睡覺");}
}
定義實現類Plant
public class Plant implements LiveAble {//重寫/實現接口的抽象方法@Overridepublic void eat() {System.out.println("吸收營養(yǎng)");}//重寫/實現接口的抽象方法@Overridepublic void breathe(){System.out.println("吸入二氧化碳呼出氧氣");}
}
定義測試類
public class Test {public static void main(String[] args) {// 創(chuàng)建實現類(子類)對象Animal a = new Animal();// 調用實現后的方法a.eat(); //吃東西a.sleep(); //閉上眼睛睡覺a.breathe(); //吸入氧氣呼出二氧化碳//創(chuàng)建實現類(子類)對象Plant p = new Plant();p.eat(); //吸收營養(yǎng)p.sleep(); //靜止不動p.breathe(); //吸入二氧化碳呼出氧氣//通過接口調用靜態(tài)方法LiveAble.drink();// Animal.drink();錯誤,找不到符號// Plant.drink();錯誤,找不到符號}
}
接口的多實現
在繼承體系中,一個類只能繼承一個父類。而對于接口而言,一個類是可以實現多個接口的,這叫做接口的多實現。并且,一個類能繼承一個父類,同時實現多個接口。
實現格式:
注意事項:
- 接口中,有多個抽象方法時,實現類如果不是抽象類就必須重寫所有抽象方法。如果抽象方法有重名的,只需要重寫一次。
- 當一個類,既繼承一個父類,又實現若干個接口時,父類中的成員方法與接口中的抽象方法重名,子類就近選擇執(zhí)行父類的成員方法
- 當一個類同時實現了多個接口,而多個接口中包含方法簽名相同的默認方法時,要么選擇保留其中一個,通過“接口名.super.方法名"的方法選擇保留哪個接口的默認方法,要么選擇自己完全重寫
接口的多繼承
一個接口能繼承另一個或者多個接口,接口的繼承也使用 extends關鍵字,子接口繼承父接口的方法。最底層的實現類(非抽象類)要實現接口里所有的抽象方法,包括接口繼承下來的。
定義接口
package sgg1.demo06;
// 父接口
interface A {void a();public default void methodA(){System.out.println("A類默認方法");}
}
// 父接口
interface B {void b();public default void methodB(){System.out.println("B類默認方法");}
}
//子接口
interface C extends A,B{}
//定義實現類
class D implements C{@Overridepublic void a() { //重寫a接口的抽象方法System.out.println("重寫a接口的抽象方法");}@Overridepublic void b() {//重寫b接口的抽象方法System.out.println("重寫b接口的抽象方法");}}
定義測試類
public class Test {public static void main(String[] args) {D d = new D();d.a(); //重寫a接口的抽象方法d.b(); //重寫b接口的抽象方法d.methodA(); //A類默認方法d.methodA(); //A類默認方法}
}
??接口與實現類對象的多態(tài)引用
實現類實現接口,類似于子類繼承父類,因此,接口類型的變量與實現類的對象之間,也可以構成多態(tài)引用。通過接口類型的變量調用方法,最終執(zhí)行的是你new的實現類對象實現的方法體。
public class TestInterface {public static void main(String[] args) {Flyable b = new Bird();b.fly(); //展翅高飛Flyable k = new Kite();k.fly(); //別拽我,我要飛}
}
interface Flyable{//抽象方法void fly();
}
class Bird implements Flyable{@Overridepublic void fly() {System.out.println("展翅高飛");}}
class Kite implements Flyable{@Overridepublic void fly() {System.out.println("別拽我,我要飛");}}