用于覆盖抽象方法的默认方法实现

时间:2016-12-15 18:09:24

标签: java interface default

Java-8中不允许以下内容:

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath;

上述代码无法编译,并显示错误消息,指出public interface Operator { default String call() throws Exception { // do some default things return performOperation(); } String performOperation(); } public abstract class AbstractTestClass { public abstract String call() throws Exception; } public class TestClass extends AbstractTestClass implements Operator { @Override public String performOperation() { // do some operation } } 需要是抽象的或覆盖调用方法。

我在想默认方法可以提供必要的覆盖。为什么这不起作用?

我被迫做以下事情:

TestClass

这缺乏我正在寻找的简洁设计。

我在this问题中看到了解决方案:

public interface Operator {
    default String doCall() throws Exception {
      // do some default things
      return performOperation();
    }

    String performOperation();
}

public abstract class AbstractTestClass {
    public abstract String call() throws Exception;
}

public class TestClass extends AbstractTestClass implements Operator {
    String call() throws Exception {
      doCall();
    }

    @Override
    public String performOperation() {
      // do some operation
    }
}

但是,该解决方案无法解释为什么编译器不允许上述干净的设计。我想理解推理,并且看看我是否有办法隐藏public class TestClass extends AbstractTestClass implements Operator { String call() throws Exception { Operator.super.call(); } @Override public String performOperation() { // do some operation } } 中的call方法。

1 个答案:

答案 0 :(得分:5)

请参阅JLS §8.4.8.4 Inheriting Methods with Override-Equivalent Signatures

  

在超类中声明abstract方法时,会对严格的default-abstract和default-default冲突规则进行此异常:来自超类层次结构的abstract-ness断言基本上胜过默认方法,使默认方法就像abstract 一样。但是,类中的abstract方法不会覆盖默认方法,因为仍然允许接口优化来自类层次结构的abstract方法的签名。

您仍然可以使用该方法的默认实现,只需使用InterfaceName.super.methodName()显式调用它:

public class TestClass extends AbstractTestClass implements Operator {
    @Override
    public String call() throws Exception {
        return Operator.super.call();
    }
    @Override
    public String performOperation() {
        // do some operation
    }
}

哦,您的performOperation()方法缺少public关键字和@Override注释。