必须扩展类A并实现某个接口的成员变量。

5
我需要在一个类中定义一个变量,它是类“ClassA”的实例,同时也实现了接口“InterfaceI”。
显然,这两个方面都可以很容易地实现:
private ClassA mVariable;
private InterfaceI mVaraible;

但是我该如何强制让对象既继承ClassA又实现InterfaceB呢?类似于以下代码:
private <? extends ClassA & InterfaceI> mVaraible;

我需要的是这个,但我不知道语法是否正确或者是否可行。同时我还需要一个get和set方法,但这可以使用通用类型(我想?)实现。

显而易见的解决方案是

public class ClassB extends ClassA implements InterfaceI{
    //whatever here
}

然而,InterfaceI和ClassA都是外部库的一部分。该库有些类扩展了ClassA和InterfaceI,但我无法编辑它们以使其扩展ClassB,因此这个解决方案行不通。


1
基本上你不能这样做。你可以在设置变量时进行检查,需要时再进行转换...但是你不能在变量本身上表达这个约束,除非将类定义为泛型。 - Jon Skeet
Java8 中有一些魔法可以允许多重继承,或某种混入... - Thufir
@Jon Skeet 当设置变量时,您会如何进行检查? - jtedit
这些类是final的吗?如果B继承A,为什么C不能继承B?我猜测B是final的……或者其他什么原因。 - Thufir
@jtedit:如果你从一个通用方法中设置它,你可以在那里使用类型系统。但是否则,你可以只使用 if (x instanceof ...) - Jon Skeet
2个回答

1
你可以使用通用类类型来实现这个,如下所示:
private class ClassB <R extends ClassA & InterfaceI> {
    R mVaraible;
}

1
我找到了一个相当粗糙的解决方法。 该类包含ClassA和InterfaceI两个引用,如下所示:
private ClassA mItemClassA;
private InterfaceI mItemInterfaceI;

set方法看起来像这样:

public void setVaraible(ClassA item){
    assert (item instanceof InterfaceI);
    mItemClassA = item;
    mItemInterfaceI = (InterfaceI) item;
}

如果该项不是InterfaceI的实例,则其他变化可能包括抛出异常、返回false等。
然后,类中的其他方法可以使用mItemClassA和mItemInterfaceI调用InterfaceI和ClassA的函数。
我现在不打算实现获取方法,但如果我这样做了,可能需要一个版本来获取接口和一个版本来获取类。

我会使用异常。默认情况下,不会检查断言。这是一个额外的标志,您必须打开它。另外+1。 - Martijn Courteaux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接