繁体   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