簡體   English   中英

擴展接口與通過匿名類實例化

[英]Extending an Interface vs Instantiating via Anonymous Class

NOTE:我知道這很危險地接近許多其他問題。 不過,我還沒有看到任何與Android的OnClickListener界面無關的東西。 我在一般意義上問。

我了解通過匿名類實例化接口之間的區別... la:

private final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        draw();
    }

};

...並擴展接口。

public class ClassyClass implements Runnable {
    ...
    //do other cool stuff here
    ...
    @Override
    public void run() {
        draw();
    }
    ...
    //and more here
    ...

}

但是,除了從諸如OnClickListener界面中獲得的明顯好處OnClickListener ,這兩種選擇還有很大的優勢嗎?

我認為擴展它將是顯而易見的選擇,因為您已經在創建該對象-無需重復工作。 這是正確的嗎?

我在一般意義上問,但是,正如我目前正在使用Runnable ,我是否想知道這兩種選擇是否都具有優勢。

好吧,這是一個顯示主要差異的示例。 這有些人為的,但這只是為了說明。

這是一個匿名版本:

class PrintBuilder {
    List<Runnable> printers = new LinkedList<>();

    List<Runnable> get() {
        return printers;
    }

    PrintBuilder add(final String line) {
        printers.add(new Runnable() {
            public void run() {
                System.out.println(line);
            }
        });

        return this;
    }
}

這是一個嵌套版本:

class PrintBuilder {
    List<Printer> printers = new LinkedList<>();

    PrintBuilder add(String line) {
        printers.add(new Printer(line));
        return this;
    }

    List<Printer> get() {
        return printers;
    }

    static class Printer implements Runnable {
        String line;

        Printer(String line) {
            this.line = line;
        }

        public void run() {
            System.out.println(line);
        }
    }
}

因此,您可以看到主要區別如下:

  • 匿名類是內部的,它具有對封閉實例的隱式引用。

特別是,在上面的示例中,PrintBuilder泄漏到內部Runnable對象死亡為止。 在第二個示例中,Runnable類是靜態的,因此它沒有此問題。

  • 匿名類要短一些。

匿名類不需要字段和構造函數,因為它們是隱式的。

  • 代碼的組織方式有很大的不同。

匿名類在實例化的地方聲明,並且如果匿名類不是很短,那么這可能對封閉類的布局造成破壞。 另一方面,如果匿名類很短,則類似函數的語法會很好。

同樣,所有班級都趨於增長,以我的經驗,當匿名班級變得太大時,這會變成一種氣味。 匿名類也很難重構為頂級類。

第一個片段定義了一個沒有名稱的類,該類實現Runnable接口(並實例化該匿名類)。 第二個定義一個帶有名稱的類,該類也實現Runnable接口。

在繼承和接口實現方面沒有任何區別,只是第二個類有一個名稱,而第一個沒有。

第二個片段允許多個類實例化Runnable實現,而第一個片段定義了一個僅從其包含的類中知道的類。 有時一個更好,有時另一個更好。

兩種方法都是有效的。 使用哪個取決於您的用法:

  • 如果在另一個類中實現接口,則可以訪問父類的受保護的方法和私有方法。
  • 如果要使事物分開並為該接口重用相同的實現,則創建單獨的類是可行的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM