一步一步學JAVA(10)-接口

接 口
1:是用關鍵字interface 定義的。
2:接口中包含的成員,最常見的有全局常量、抽象方法。
注意:接口中的成員都有固定的修飾符。
成員變量:public static final
成員方法:public abstract

interface Inter{
    public static final int x = 3;
    public abstract void show();
}


3:接口中有抽象方法,說明接口不可以實例化。接口的子類必須實現了接口中所有的抽象方法後,該子類纔可以實例化。否則,該子類還是一個抽象類。
4:類與類之間存在着繼承關係,類與接口中間存在的是實現關係。
繼承用extends ;實現用implements ;
5:接口和類不一樣的地方,就是,接口可以被多實現,這就是多繼承改良後的結果。java 將多繼承機制通過多現實來體現。
6:一個類在繼承另一個類的同時,還可以實現多個接口。所以接口的出現避免了單繼承的侷限性。還可以將類進行功能的擴展。
7:其實java 中是有多繼承的。接口與接口之間存在着繼承關係,接口可以多繼承接口。
接口都用於設計上,設計上的特點:(可以理解主板上提供的接口)
1:接口是對外提供的規則。
2:接口是功能的擴展。
3:接口的出現降低了耦合性。
抽象類與接口
抽象類:一般用於描述一個體系單元,將一組共性內容進行抽取,特點:可以在類中定義抽象內容讓子類實現,可以定義非抽象內容讓子類直接使用。它裏面定義的都是一些體系中的基本內容。
接口:一般用於定義對象的擴展功能,是在繼承之外還需這個對象具備的一些功能。
抽象類和接口的共性:都是不斷向上抽取的結果。
抽象類和接口的區別:
1:抽象類只能被繼承,而且只能單繼承。
接口需要被實現,而且可以多實現。
2:抽象類中可以定義非抽象方法,子類可以直接繼承使用。
接口中都有抽象方法,需要子類去實現。
3:抽象類使用的是 is a 關係。
接口使用的 like a 關係。
4:抽象類的成員修飾符可以自定義。
接口中的成員修飾符是固定的。全都是public 的。
在開發之前,先定義規則,A 和B 分別開發,A 負責實現這個規則,B 負責使用這個規則。至於A 是如何對規則具體實現的,B 是不需要知道的。這樣這個接口的出現就降低了A 和B 直接耦合性。
------------------------------------------------------------------------------------------------
內部類:如果A 類需要直接訪問B 類中的成員,而B 類又需要建立A 類的對象。這時,爲了方便設計和訪問,直接將A 類定義在B 類中。就可以了。A 類就稱爲內部類。內部類可以直接訪問外部類中的成員。而外部類想要訪問內部類,必須要建立內部類的對象。

class Outer{
    int num = 4;
    class Inner {
        void show(){
            System.out.println("inner show run "+num);
        }
    }
    public void method(){
        Inner in = new Inner();//創建內部類的對象。
        in.show();//調用內部類的方法。
    }
}


當內部類定義在外部類中的成員位置上,可以使用一些成員修飾符修飾 private、static。
1:默認修飾符。
直接訪問內部類格式:外部類名.內部類名 變量名 = 外部類對象.內部類對象;
Outer.Inner in = new Outer.new Inner();//這種形式很少用。
但是這種應用不多見,因爲內部類之所以定義在內部就是爲了封裝。想要獲取內部類對象通常都通過外部類的方法來獲取。這樣可以對內部類對象進行控制。
2:私有修飾符。
通常內部類被封裝,都會被私有化,因爲封裝性不讓其他程序直接訪問。
3:靜態修飾符。
如果內部類被靜態修飾,相當於外部類,會出現訪問侷限性,只能訪問外部類中的靜態成員。
注意;如果內部類中定義了靜態成員,那麼該內部類必須是靜態的。
內部類編譯後的文件名爲:“外部類名$內部類名.java”;
爲什麼內部類可以直接訪問外部類中的成員呢?
那是因爲內部中都持有一個外部類的引用。這個是引用是 外部類名.this
內部類可以定義在外部類中的成員位置上,也可以定義在外部類中的局部位置上。
當內部類被定義在局部位置上,只能訪問局部中被final 修飾的局部變量。
匿名內部類:沒有名字的內部類。就是內部類的簡化形式。一般只用一次就可以用這種形式。匿名內部類其實就是一個匿名子類對象。想要定義匿名內部類:需要前提,內部類必須繼承一個類或者實現接口。
匿名內部類的格式:new 父類名&接口名(){ 定義子類成員或者覆蓋父類方法 }.方法。
匿名內部類的使用場景:
當函數的參數是接口類型引用時,如果接口中的方法不超過3 個。可以通過匿名內部類來完成參數的傳遞。
其實就是在創建匿名內部類時,該類中的封裝的方法不要過多,最好兩個或者兩個以內。

//面試
//1

new Object(){
    void show(){
    System.out.println("show run");
    }
}.show();


//2

Object obj = new Object(){
    void show(){
        System.out.println("show run");
    }
};
obj.show();


1 和2 的寫法正確嗎?有區別嗎?說出原因。
寫法是正確,1 和2 都是在通過匿名內部類建立一個Object 類的子類對象。
區別:
第一個可是編譯通過,並運行。
第二個編譯失敗,因爲匿名內部類是一個子類對象,當用Object 的obj 引用指向時,就被提升爲了Object 類型,而編譯時檢查Object 類中是否有show 方法,所以編譯失敗。

class InnerClassDemo6 {
    +(static)class Inner{
    void show(){}
    }
    public void method(){
        this.new Inner().show();//可以
    }
    public static void main(String[] args) {//static 不允許this
        This.new Inner().show();//錯誤,Inner 類需要定義成static
    }
}

interface Inter{
    void show();
}
class Outer{//通過匿名內部類補足Outer 類中的代碼。
    public static Inter method(){
        return new Inter(){
            public void show(){}
        };
    }
}
class InnerClassDemo7 {
    public static void main(String[] args) {
        Outer.method().show();
        /*
        Outer.method():意思是:Outer 中有一個名稱爲method 的方法,而且這個方法是靜態的。
        Outer.method().show():當Outer 類調用靜態的method 方法運算結束後的結果又調用了show 方                            法,意味着:method()方法運算完一個是對象,而且這個對象是Inter 類型的。
        */
        function (new Inter(){
            public void show(){}
        }); //匿名內部類作爲方法的參數進行傳遞。
    }
    public static void function(Inter in){
        in.show();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章