Java 接口和抽象類

接口工具

概念spa

Java接口是一系列方法的聲明,是一些方法特徵的集合,一個接口只有方法的特徵沒有方法的實現,所以這些方法能夠在不一樣的地方被不一樣的類實現,而這些實現能夠具備不一樣的行爲(功能)。.net

特色設計

  • 在接口中聲明的方法默認是抽象的(即只有方法標識符,而沒有方法體)。
  • 抽象方法只能存在於抽象類或者接口中,但抽象類中卻能存在非抽象方法,即有方法體的方法。接口是百分之百的抽象類。
  • 不能直接實例化一個接口,由於接口中的方法都是抽象的,沒有方法體,可是,咱們可使用接口類型的引用指向一個實現了該接口的對象,而且能夠調用這個接口中的方法。
  • 一個類能夠實現多個接口。
  • 一個接口能夠繼承於另外一個接口,或者另外一些接口,接口也能夠繼承,而且能夠多繼承。
  • 一個類若是要實現某個接口的話,那麼它必需要實現這個接口中的全部方法。
  • 接口中全部的方法都是public abstract 的,全部的屬性都是public static final的。
  • 接口用來彌補類沒法實現多繼承的侷限。
  • 接口也能夠用來實現解耦。

 

語法實現code

爲了聲明一個接口,咱們使用interface關鍵字,在接口中的全部方法都必須只聲明方法標識,而不聲明具體的方法體,由於具體的方法體的實現是由實現該接口的類完成,使用implments實現接口。接口中的默認屬性爲Public Static Final。一個類實現這個接口必須實現這個接口中定義的全部的抽象方法。對象

一個簡單的接口:擁有全局變量和抽象方法。blog

 

抽象類繼承

概念接口

普通類是一個完善的功能類,能夠直接產生實例化對象,而且在普通類中能夠包含有構造方法、普通方法、static方法、常量和變量等內容。而抽象類是指在普通類的結構裏面增長抽象方法的組成部分。那麼什麼叫抽象方法呢?在全部的普通方法上面都會有一個「{}」,這個表示方法體,有方法體的方法必定能夠被對象直接使用。而抽象方法,是指沒有方法體的方法,同時抽象方法還必須使用關鍵字abstract作修飾。而擁有抽象方法的類就是抽象類,抽象類要使用abstract關鍵字聲明。io

特色

  • 抽象方法必須爲public或者protected(由於若是爲private,則不能被子類繼承,子類便沒法實現該方法),缺省狀況下默認爲public;
  • 抽象類不能直接實例化,須要依靠子類採用向上轉型的方式處理;
  • 抽象類必須有子類,使用extends繼承,一個子類只能繼承一個抽象類;
  • 子類(若是不是抽象類)則必須覆寫抽象類之中的所有抽象方法(若是子類沒有實現父類的抽象方法,則必須將子類也定義爲abstract類);
  • 因爲抽象類裏會存在一些屬性,那麼抽象類中必定存在構造方法,其存在目的是爲了屬性的初始化。而且子類對象實例化的時候,依然知足先執行父類構造,再執行子類構造的順序。
  • 抽象類不能用final聲明,由於抽象類必須有子類,而final定義的類不能有子類;
  • 外部抽象類不容許使用static聲明,而內部的抽象類容許使用static聲明。使用static聲明的內部抽象類至關於一個外部抽象類,繼承的時候使用「外部類.內部類」的形式表示類名稱。
  • 任什麼時候候,若是要執行類中的static方法的時候,均可以在沒有對象的狀況下直接調用,對於抽象類也同樣。

 

【範例】

定義接口格式
[public]interface 接口名稱 [extends父接口名列表] { //靜態常量 [public] [static] [final] 數據類型變量名=常量值; //抽象方法 [public] [abstract] [native] 返回值類型方法名(參數列表); } 實現接口格式: [修飾符] class 類名[extends 父類名] [implements 接口A,接口B,···] { 類成員變量和成員方法; 爲接口A中的全部方法編寫方法體,實現接口A; 爲接口B中的全部方法編寫方法體,實現接口B; }

 

具體實例
//簡單接口
interface demoA{ //全局變量用默認用public static final修飾
       final int a=6; //抽象方法默認用 public abstract 修飾
       void show(); } //接口實現
class testDemoB implements demoA{ //實現接口中因此抽象方法
       public void show(){ System.out.println("歡迎你"); } }

接口和抽象類的區別

接口和抽象類最大的區別,就在於Java抽象類能夠提供某些方法的部分實現,而Java接口不能夠,這大概就是Java抽象類惟一的優勢吧,但這個優勢很是有用。若是向一個抽象類里加入一個新的具體方法時,那麼它全部的子類都一會兒都獲得了這個新方法,而Java接口作不到這一點,若是向一個Java接口裏加入一個新方法,全部實現這個接口的類就沒法成功經過編譯了,由於你必須讓每個類都再實現這個方法才行,這顯然是Java接口的缺點。
一個抽象類的實現只能由這個抽象類的子類給出,也就是說,這個實現處在抽象類所定義出的繼承的等級結構中,而因爲Java語言的單繼承性,因此抽象類做爲類型定義工具的效能大打折扣。在這一點上,Java接口的優點就出來了,任何一個實現了一個Java接口所規定的方法的類均可以具備這個接口的類型,而一個類能夠實現任意多個Java接口,從而這個類就有了多種類型。
不難看出,Java接口是定義混合類型的理想工具,混合類代表一個類不只僅具備某個主類型的行爲,並且具備其餘的次要行爲。
 
在語法上,抽象類和接口有着如下不一樣:
1.abstract class在Java語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。可是,一個類卻能夠實現多個interface。 繼承抽象類使用的是extends關鍵字,實現接口使用的是implements關鍵字,繼承寫在前面,實現接口寫在後面。若是實現多個接口,中間用逗號分隔。
例:
public class Main extends JApplet public class Main implements Runnable public class Main extends JApplet implements ActionListener public class Main extends JApplet implements ActionListener, Runnable
2.在abstract class中能夠有本身的數據成員,也能夠有非abstract的成員方法,而在interface中,只可以有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中通常不定義數據成員),全部的成員方法都是abstract的。
3.abstract class和interface所反映出的設計理念不一樣。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係。
4.實現接口的類必須實現其中的全部方法,繼承自抽象類的子類實現全部的抽象方法。抽象類中能夠有非抽象方法。接口中則不能有實現方法。
5.接口中定義的變量默認是public static final 型,且必須給其初值,因此實現類中不能從新定義,也不能改變其值。
6.抽象類中的變量默認具備 friendly權限,其值能夠在子類中從新定義,也能夠從新賦值。
7.接口中的方法默認都是 public abstract 類型的。
 
拓展:

轉型是在繼承的場景下的用法。
向上轉型:子類對象轉爲父類,父類能夠是接口。公式:Father f = new Son();Father是父類或接口,son是子類。向上轉型不用強制轉型。
向下轉型:父類對象轉爲子類(爲了將向上轉型的對象還原)。

公式:

Father f; Son s = (Son)f;

 

向上轉型

向上轉型後父類的引用所指向的屬性是父類的屬性,若是子類重寫了父類的方法,那麼父類引用指向的或者調用的方法是子類的方法,這個叫動態綁定。

public class Animal { public void eat(){ System.out.println("animal"); } } public class Cat extends Animal{ public void eat(){ System.out.println("Cats"); } public void run(){ System.out.println("run"); } } public class Main { public static void main(String[] args) { Animal animal = new Cat(); //向上轉型
        animal.eat(); // Cats // 向上轉型後父類引用不能調用子類本身的方法, 調用run方法會報錯
 animal.run(); } }

向上轉型的做用,減小重複代碼,父類爲參數,調有時用子類做爲參數,就是利用了向上轉型。這樣使代碼變得簡潔。

public void eat(Animal animal){ animal.eat(); } // 全部繼承animal的均可以調用
eat(new Dog()); eat(new Cat());

向上轉型後沒法調用子類本來的特有的方法和屬性,爲此這裏引入向下轉型來還原。

 

向下轉型

向下轉型的前提是父類對象指向的是子類對象(也就是說,在向下轉型以前,它得先向上轉型)。

Animal a = new Cat(); Cat c = ((Cat) a); // 如下代碼會報錯
Animal a1 = new Animal(); Cat c1 = ((Cat) a1);

 

因此向下轉型前要先用instanceof進行判斷。

注意:

1.類與類之間的關係爲繼承,只能單繼承,但能夠多層繼承。

2.類與接口之間的關係爲實現,既能夠單實現,也能夠多實現。

3.接口與接口之間的關係爲繼承,既能夠單繼承,也能夠多繼承。

 

參考來源:https://blog.csdn.net/sysuzhyupeng/article/details/84890147

相關文章
相關標籤/搜索