功能
在Java語言規範中,一個方法的特徵僅包括方法的名字,參數的數目和種類,而不包括方法的返回類型,參數的名字以及所拋出來的異常。在Java
編譯器檢查方法的
重載時,會根據這些條件判斷兩個方法是否是重載方法。但在Java編譯器檢查方法的置換時,則會進一步檢查兩個方法(分處超類型和子類型)的返還類型和拋出的
異常是否相同。
接口實現和類繼承的規則不同,為了數據的安全,繼承時一個類只有一個直接父類,也就是單繼承,但是一個類可以實現多個接口,接口彌補了類的不能多繼承缺點,繼承和接口的雙重設計既保持了類的數據安全也變相實現了多繼承。
Java接口本身沒有任何實現,因為Java接口不涉及表象,而只描述public行為,所以Java接口比Java
抽象類更抽象化。但是接口不是類,不能使用new 運算符實例化一個接口。如 x=new comparable(......);//這個是錯誤來的。但是可以聲明接口變數Comparable x; //這是允許的。
Java接口的方法只能是抽象的和公開的,Java接口不能有
構造器,Java接口可以有public、static和final屬性。即接口中的屬性可以定義為 public static final int value=5;
接口把方法的特徵和方法的實現分割開來。這種分割體現在接口常常代表一個角色,它包裝與該角色相關的操作和屬性,而實現這個接口的類便是扮演這個角色的演員。一個角色由不同的演員來演,而不同的演員之間除了扮演一個共同的角色之外,並不要求其它的共同之處。
使用
兩個類中的兩個類似的功能,調用他們的類動態的決定一種實現,那他們提供一個抽象父類,子類分別實現父類所定義的方法。
問題的出現:Java是一種單繼承的語言,一般情況下,哪個具體類可能已經有了一個
超類,解決是給它的父類加父類,或者給它父類的父類加父類,直到移動到類等級結構的最頂端。這樣一來,對一個具體類的可插入性的設計,就變成了對整個等級結構中所有類的修改。
可插入性
在一個等級結構中的任何一個類都可以實現一個接口,這個接口會影響到此類的所有子類,但不會影響到此類的任何
超類。此類將不得不實現這個接口所規定的方法,而其子類可以從此類自動繼承這些方法,當然也可以選擇置換掉所有的這些方法,或者其中的某一些方法,這時候,這些子類具有了可插入性(並且可以用這個接口類型裝載,傳遞實現了他的所有子類)。
我們關心的不是那一個具體的類,而是這個類是否實現了我們需要的接口。
接口提供了關聯以及方法調用上的可插入性,軟體系統的規模越大,生命周期越長,接口使得軟體系統的靈活性和可擴展性,可插入性方面得到保證。
類型
使用Java接口將軟體單位與內部和外部耦合起來。使用Java接口不是具體的類進行變數的類型聲明,方法的返還類型聲明,參量的類型聲明,以及數據類型的轉換。
在理想的情況下,一個具體的Java類應當只實現Java接口和抽象Java類中聲明的方法,而不應當給多餘方法。
等級結構
Java接口(以及
抽象類)一般用來作為一個類型的等級結構的起點。
如果一個類已經有了一個主要的超類型,那么通過實現一個接口,這個類可以擁有另一個次要的超類型,這種次要的超類型叫做混合類型。
分類
單方法接口
以下是引用片段:
public interface Actionlistener{
public abstract void actionPerformed(ActionEvent event);
}
僅且只有一個方法,只有實現了這個接口(重寫這個接口中的唯一一個方法),你才有資格去事件監聽器列表里註冊(參數為Actionlistener類型),當事件源變動時,自動調用這個唯一的actionPerformed方法。
標識接口
是沒有任何方法和屬性的接口。標識接口不對實現它的類有任何語意上的要求,它僅僅表明了實現它的類屬於一個特定的類型(傳遞)。
不推薦過多的使用標識接口。
常量接口
用Java接口來聲明一些常量,然後由實現這個接口的類使用這些常量(以前在做畫板的時候這么乾過)。建議不要模仿這種常量接口的做法。
【範例】
定義接口格式:
[public]interface 接口名稱 [extends父接口名列表]
{
//靜態常量
[public] [static] [final] 數據類型變數名=常量值;
//抽象方法
[public] [abstract] [native] 返回值類型方法名(參數列表);
}
實現接口格式:
[修飾符] class 類名[extends 父類名] [implements 接口A,接口B,···]
{
類成員變數和成員方法;
為接口A中的所有方法編寫方法體,實現接口A;
為接口B中的所有方法編寫方法體,實現接口B;
}
實例:
本例定義接口AreaInterface,其中有靜態常量pai和求面積的抽象方法area()。類Circle和類Rectangle實現了AreaInterface接口,即為接口中的抽象方法area()編寫了滿足各自要求的方法體,分別求圓形和長方形的面積。
程式:AreaInterface.java
1 2 3 4 5 | package jiekou; public interface AreaInterface{ double pai=Math.PI; double area(); } |
程式:Circle.java
1 2 3 4 5 6 7 8 9 10 11 12 13 | package jiekou; public class Circle implements AreaInterface{ double r; public Circle(double x){ r=x; } //實現接口中的抽象方法,求圓面積 public double area(){ return pai * r * r; } public String toString(){ return "圓:r="+r+"\tarea="+area(); } } |
程式:Rectangle.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package jiekou; public class Rectangle implements AreaInterface{ double x,y; public Rectangle(double a,double b){ x=a; y=b; } public double area()//實現接口中的抽象方法,求長方形面積 { return x * y; } public String toString() { return "長方形:x="+x+";y="+y+"\t" area=+area(); } } |
Java接口和Java抽象類最大的一個區別,就在於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 類型的。