Java中:接口,抽象類,內部類

Java8中的接口

public interface Output {
    //接口裏定義的成員變量只能是常量
    //默認使用public static final修飾
    int MAX_CACHE_LINE = 50;

    //接口裏定義的普通方法只能是public的抽象方法
    void out();

    void getData(String msg);

    //接口中定義的默認方法,需要使用default修飾
    default void print(String... msgs) {
        for (String msg : msgs) {
            System.out.println(msg);
        }
    }

    //接口中定義類方法,需要使用static修飾
    static String staticTest(){
        return "接口裏的類方法";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Java8中允許在接口中定義默認方法,默認方法必須使用default修飾,該方法不能使用static修飾,無論程序是否指定,默認方法總是使用public修飾。由於默認方法並沒有static修飾,因此不能直接使用接口來調用默認方法,需要使用接口的實現類的實例來調用這些默認方法。

Java8中允許在接口中定義類方法,類方法必須使用static修飾,該方法不能使用default修飾,無論程序是否指定,類方法總是使用public修飾。類方法可以直接使用接口來調用。

接口和抽象類

  • 相同點 
    • 接口和抽象類都不能被實例化,他們都位於繼承樹的頂端,用於被其他類實現和繼承。
    • 接口和抽象類都可以包含抽象方法,實現接口或繼承抽象類的普通子類都必須實現這些抽象方法。
  • 區別: 
    1. 接口裏只能包含抽象方法和默認方法,不能爲普通方法提供方法實現;抽象類則完全可以包含普通方法。
    2. 接口裏不能定義靜態方法;抽象類裏可以定義靜態方法。
    3. 接口裏只能定義靜態常量,不能定義普通成員變量;抽象類裏則既可以定義普通成員變量,也可以定義靜態常量。
    4. 接口裏不包含構造器;抽象類裏可以包含構造器,抽象類裏的構造器並不是用於創建對象,而是讓其子類調用這些構造器來完成屬於抽象類的初始化操作。
    5. 接口裏不能包含初始化塊;但抽象類則完全可以包含初始化塊。
    6. 一個類最多只能有一個直接父類,包括抽象類;但一個類可以直接實現多個接口,通過實現多個接口可以彌補Java單繼承的不足。

內部類

把一個類放在另一個類的內部定義,這個定義在其他類內部的類就被稱爲內部類(也叫嵌套類),包含內部類的類也被稱爲外部類(也叫宿主類)

內部類比外部類可以多用三個修飾符:private、protected、static

非靜態內部類不能擁有靜態成員

在一個類的方法中定義的內部類叫做局部內部類;其他的叫做成員內部類。

非靜態內部類

成員內部類中沒有使用static修飾的內部類是非靜態內部類

非靜態內部類對象和外部類對象的關係是?

  • 非靜態內部類對象必須寄生在外部類對象裏,而外部類對象則不必一定有費靜態內部類對象寄生其中。
  • 如果存在一個非靜態內部類對象,則一定存在一個被他寄生的外部類對象。
  • 但外部類對象存在時,外部類對象裏不一定寄生了非靜態內部類對象。
  • 因此外部類對象訪問非靜態內部類成員時,可能非靜態普通內部類根本不存在。
  • 而非靜態內部類對象訪問外部類成員時,外部類對象一定存在。

靜態內部類

使用static修飾的內部類被稱爲靜態內部類(也叫類內部類)。這個內部類屬於外部類本身,而不屬於外部類的某個對象。

靜態內部類可以包含靜態成員,也可以包含非靜態成員。

爲什麼靜態內部類的實例方法不能訪問外部類的實例屬性?

  • 靜態內部類是外部類的類相關的,而不是外部類的對象相關的。
  • 靜態內部類對象不是寄生在外部類的實例中,而是寄生在外部類的類本身中。
  • 當靜態內部類對象存在時,並不存在一個被他寄生的外部類對象,靜態內部類對象只持有外部類的類引用,沒有持有外部類對象的引用。
  • 如果允許靜態內部類的實例方法訪問外部類的實例成員,但找不到被寄生的外部類對象,這將引起錯誤。

局部內部類

如果把一個內部類放在方法裏定義,則這個內部類就是一個局部內部類,局部內部類僅在該方法裏有效。

實際開發很少使用

匿名內部類

匿名內部類適合創建那種只需要一次使用的類。

創建匿名內部類時會立即創建一個該類的實例,這個類定義立即消失,匿名內部類不能重複使用。

匿名內部類格式:

new 實現接口() | 父類構造器(實參列表)
{
    //匿名內部類的類體部分
}
  • 1
  • 2
  • 3
  • 4
  • 5

最常用的創建匿名內部類的方式是需要創建某個接口類型的對象

interface Product {
    public double getPrice();

    public String getName();
}

public class AnonymousTest {
    public void test(Product p) {
        System.out.println("買了一個" + p.getName() + ",花了" + p.getPrice());
    }

    public static void main(String args[]) {
        AnonymousTest ta = new AnonymousTest();

        //調用test方法時,需要傳入一個Product參數
        //此處傳入其匿名實現類的實例
        ta.test(new Product() {
            @Override
            public double getPrice() {
                return 12.3;
            }

            @Override
            public String getName() {
                return "U盤";
            }
        });
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Lambda表達式

Lambda表達式支持代碼塊作爲方法參數,允許使用更簡潔的代碼來創建只有一個抽象方法的接口(這種接口被稱爲函數式接口)的實例。

比如,有匿名內部類程序:

public class CommandTest {
    public static void main(String args[]) {
        ProcessArray pa = new ProcessArray();
        int[] target = {2, 1, -5, 3};
        pa.process(target, new Command() {
            @Override
            public void process(int[] target) {
                int sum = 0;
                for (int tmp : target) {
                    sum += tmp;
                }
                System.out.println("數組元素的總和是:" + sum);
            }
        });
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

改爲Lambda表達式代替匿名內部類:

public class CommandTest {
    public static void main(String args[]) {
        ProcessArray pa = new ProcessArray();
        int[] target = {2, 1, -5, 3};
        pa.process(target, (int[] array) -> {
            int sum = 0;
            for (int tmp : array) {
                sum += tmp;
            }
            System.out.println("數組元素的總和是" + sum);
        });
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
版權聲明:本文爲博主原創文章,轉載請註明來源,感謝!
發佈了6 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章