簡體   English   中英

Java 接口:在實現類中使用默認方法實現

[英]Java Interface : Use default method implementation in implementation classes

我有一個接口,它的 2 個或更多實現說,

public interface IProcessor {
  default void method1() {
   //logic
  }
  default void method2() {
   //logic
  }
  public void method3();
  public void method4();
}

這里, method1method2實現邏輯在所有多個多個實現類中是通用的。 所以定義為默認方法。 所以只有rest的方法可以在實現類中被覆蓋。

public CarImpl implements IProcessor {
  @Override 
  public void method3() {
    //logic
  }
  @Override 
  public void method4() {
    //logic
  }
}

public VanImpl implements IProcessor {
  @Override 
  public void method3() {
    //logic
  }
  @Override 
  public void method4() {
    //logic
  }
}

有沒有更好的方法可以在沒有默認方法和相應實現類中沒有冗余代碼的情況下實現這一目標? 因為如果default方法中的代碼增加,那么界面看起來很笨拙。

可以覆蓋默認方法

你說:

所以只有rest的方法可以在實現類中被覆蓋。

那里的“唯一”一詞是不正確的。 實現 class 確實可以覆蓋接口中的默認方法。 因此這里使用的單詞default作為關鍵字,意思是:如果在運行時沒有其他實現代碼,則使用此方法代碼。

這是一個愚蠢的人為設計的示例,其中我們定義了一個帶有默認方法isJuicy返回true的接口Fruit 我們有兩個子類, OrangeBanana 第一個沒有覆蓋isJuicy ,因此它的行為來自默認方法。 第二個演示您可以覆蓋默認方法。 在這里,我們看到覆蓋返回false

package work.basil.example;

public class OverridingDefault
{
    public static void main ( String[] args )
    {
        OverridingDefault app = new OverridingDefault();
        app.demo();
    }

    private void demo ( )
    {
        System.out.println( "new Orange().isJuicy(): " + new Orange().isJuicy() );
        System.out.println( "new Banana().isJuicy(): " + new Banana().isJuicy() );
    }

    public interface Fruit
    {
        default boolean isJuicy ( )
        {
            return true;
        }
    }

    public class Orange implements Fruit
    {
    }

    public class Banana implements Fruit
    {
        @Override
        public boolean isJuicy ( )
        {
            return false;
        }
    }
}

跑的時候。

new Orange().isJuicy(): true
new Banana().isJuicy(): false

優先使用抽象類而不是默認方法

您問:

有沒有更好的方法可以在沒有默認方法並且在各個實現類中沒有冗余代碼的情況下實現這一目標?

我建議您不要為此使用default接口方法。

將默認方法添加到 Java 接口的想法和技術本身並不是一個功能,而是作為另一個問題的解決方案:在現有接口上改造功能以支持新的 lambda 功能,但不會破壞數百萬 ZD5238AZ7880E15EA218 程序員的現有代碼。否則會在向現有接口添加方法時發生。 通過在接口上發明default方法,Java 團隊能夠向現有接口添加更多方法,同時減輕所有現有實現對實現這些新方法的需求。 新功能,無需破解代碼,是 Java 的標志。

Brian Goetz 2013-09的 Lambda 的 State 所述

默認方法(...) 的目的是使接口在初始發布后能夠以兼容的方式進行演變。

我自己的觀點是,程序員通常不會期望將行為內置到您的接口中。 Java 中接口的經典用法是根據 方法簽名定義合約,而不是定義行為(代碼)。 所以考慮添加添加行為(代碼)作為默認方法僅作為最后的手段。

相反,將您的接口定義為合同,沒有默認方法。 至少一開始沒有默認方法; 您可能會發現以后需要像 Brian Goetz 和 Java 團隊一樣稍后添加默認方法。 但從合同開始。

然后定義一個實現該接口的抽象 class。 任何要在各個子類之間共享的行為(代碼)都可以移動到這個抽象的 class 中。

然后 go 定義繼承自抽象 class 的子類,具體類。

使用這種經典且通用的接口 + 抽象 class + 具體類的方法,您可以靈活地進行更改,並使測試更容易(使用存根而不是真實類),同時從一個地方有效地共享代碼,但允許在需要時進行覆蓋。

你沒有做錯任何事,雖然我會說抽象類更適合這種情況,當你有跨多個實現共享的方法實現( method1method2 )時。

如果您仍然希望它是一個接口,請創建一個接口和一個抽象 class 擴展該接口。

暫無
暫無

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

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