接口
接口里面的方法全部是抽象方法。
接口是從多個相似類中抽象出來的規范,接口體現了規范(設計)和實現分離的設計哲學,接口本身並不提供任何實現。
訪問權限 interface 接口名{
//成員變量默認使用(也只能是)public static final修飾,完全等價於public static final int MAX_SIZE=50;
//接口中不能有構造函數、初始化塊,所以成員變量必須咋在定義時就指定初始值
int MAX_SIZE=50;
//接口中可以包含私有方法,但私有方法必須有方法體
private void test1(){
.......
}
//接口中可以有默認方法,但默認方法必須要有方法體
default void test2(){
........
}
//接口中可以定義類方法,但類方法必須要有方法體
//類方法可指定為private、public,默認為public,不能使用default修飾
static void test3(){
......
}
//普通實例方法默認使用(也只能使用)public abstract修飾,不能有方法體
//等價於public abstract void test();
void test4();
//接口中也可以定義內部類、內部接口、內部枚舉,均默認使用(也只能使用)public static修飾
}
接口與類同級別,一個.java文件中最多只能有一個public接口,.java文件必須與public接口同名。
類只支持單繼承,接口支持多繼承。
class 類A extends 類B{........}
interface 接口A extends 接口B,接口C{.......}
一個類可以實現多個接口:
class 類A implement 接口A,接口B{........}
一個類可以在繼承的同時實現多個接口:
class 類A extends 類B implements 接口A,接口B{.......}
類實現接口中的方法時,一般只能使用public修飾方法,因為子類方法的權限必須大於等於父類的。
當一個程序中使用接口時,接口是多個模塊間的耦合標准;當在多個應用程序間使用接口時,接口是程序之間的通信標准。
接口類似於系統的總綱,它制定了系統各模塊應該遵循的標准。系統中的接口不應該經常改變,一旦接口改變,會影響與接口耦合的所有模塊。
抽象類作為多個子類的共同父類,它體現的是一種模板式設計,相當於系統實現過程中的中間產品。
利用接口的多繼承可以彌補類單繼承的不足。
抽象類中可以包含構造函數,但抽象類的構造函數不用於創建對象,而用於抽象類的初始化,這些構造器是給子類的構造函數調用的。
面向接口編程
面向接口編程可以降低各模塊間的耦合。
1、簡單工廠模式
在類A中要使用類B的對象,原來是在類A中創建類B的對象:
class A {
B b=new B();
.......//調用b中的方法
}
這樣不好維護:如要修改類B,則還需修改所有使用了類B的地方。如果使用類B的地方很多,就需要修改很多地方,東一個,西一個,不好找,不好維護。
簡單工廠模式:
class A{
IB ib; //IB是B類對應的接口
ib=XXXFactory.getB(); //通過工廠生產B類對象
.......//調用ib中的方法
}
再定義一個工廠類,生產該接口的子類的對象:
class xxxFactory{
public static B getB(){
......//創建並返回一個B類對象
}
.......
public static C getC(){
.......//創建並返回一個C類對象
}
}
這樣只與對應的接口耦合,修改B類時只需修改B類、工廠類,方便維護,主要是不用東一個、西一個地找,好修改。
2、命令模式
要執行某個方法、完成某個行為,但之前並不知道這個方法、行為具體是什么,執行時才知道該方法體、行為。
先定義一個接口:
public Interface Command{
public void func(參數表);
}
再定義一個調用類:
public class Call{
public void callCommand(參數表,Command command){ //上面兩個參數表要相同
command.func(參數表); //執行接口中的方法
}
}
然后寫多個子類實現該接口:
public class CommandA implement Command{
public void func(參數表){
......//A行為、命令
}
}
public class CommandB implement Command{
public void func(參數表){
......//B行為、命令
}
}
最后在要用的地方使用即可:
public class xxx{
......
Call call=new Call();
call.callCommand(參數表,new CommandA()); //使用CommandA的func()來處理參數表
call.callCommand(參數表,new CommandB()); //使用CommandB的func()來處理參數表
}