可以通过接口的“default”接口调用一个继承超类的方法吗?

时间:2017-11-03 03:20:05

标签: java inheritance

我确实查看了建议的可能重复项。他们不会问这个问题,而是相关的事情。

我在Java 8中有这个理想的结构:

class BaseClass {
   int method(int arg) {...}  // does 99% of the work
}

interface MixinInterface { // intended only for subclasses of BaseClass

   default int method(int arg) {
        // what I want:
        // effectively Subclass.super.method(arg) 
        int ret = this.super.method(arg);
        { do some embellishment on super.method results }
        return(ret);
   }

}

class Subclass
    extends BaseClass
    implements MixinInterface
{
}

是的,可以使用Reflection执行此操作,或者将callSuperMethod()方法添加到继承类的接口,但它要么是真的很慢,要么是凌乱的。通过反射,可以找到继承接口的对象的超类(并因此通过接口的默认值覆盖它的“super.method”),从超类“class”获取方法句柄并调用它。

1 个答案:

答案 0 :(得分:1)

基本上你不能在界面和基类中使用相同的方法签名,并且仍然可以独立使用这两种方法签名,即使你需要使用MethodHandles的反思也很复杂。

一个选项是删除extends BaseClass并执行类似于装饰器模式的操作。

class BaseClass {
   int method(int arg) {...}  // does 99% of the work
}

interface MixinInterface { // intended only for subclasses of BaseClass

   default int method(int arg) {
        // what I want:
        // effectively Subclass.super.method(arg) 
        int ret = getBaseClass().method(arg);

        return(ret);
   }

   BaseClass getBaseClass();

}

class Subclass implements MixinInterface
{
    private final BaseClass baseClass;

    public Subclass(BaseClass baseClass) {
        this.baseClass = baseClass;
    }

    @Override
    public BaseClass getBaseClass() {
        return baseClass;
    }

   // forward other method calls to baseClass (can be included in the MixinInterface as well)

}

另一个选项重命名装饰器方法并在BaseCase中使用它,这样implements MixinInterface几乎是多余的,应该用静态方法调用替换(特别是如果你只有一个装饰方法)。装饰器链接不太容易用这个。

abstract class BaseClass {

    abstract int methodDecorator(int originalReturn);

    int method(int arg) {
        // do 99% of the work
        return methodDecorator(0);
    } 
}

interface MixinInterface {
    default int methodDecorator(int arg) {
        return arg;
    }
}

class Subclass extends BaseClass implements MixinInterface {
    @Override
    public int methodDecorator(int originalReturn) {
        // Sadly you need this forwarding, making this approach a bit clunky
        return MixinInterface.super.methodDecorator(originalReturn);
    }
}