【问题标题】:Member variable which must extend class A and implement some interface必须扩展类 A 并实现某些接口的成员变量
【发布时间】:2014-01-02 04:18:05
【问题描述】:

我需要在一个类中有一个变量,它是“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,因此这个解决方案不起作用。

【问题讨论】:

  • 你不能,基本上。您可以在设置变量时检查它,然后在需要时进行强制转换......但是如果不使类成为通用类,就无法对变量本身表达这种约束。
  • Java8 中有一些魔法允许多重继承,或者某种混合...
  • @Jon Skeet 设置变量时如何检查?
  • 课程是最终的吗?如果B扩展A,为什么C不能扩展B?我猜 B 是最终的……或者什么的。
  • @jtedit:好吧,如果您从泛型方法设置它,您可以使用那里的类型系统。但除此之外,您可以使用if (x instanceof ...)

标签: java extends implements


【解决方案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 调用函数。

我现在不打算实现 get 方法,但如果我这样做了,可能必须有一个版本来获取接口和一个版本来获取类。

【讨论】:

  • 我会改用异常。默认情况下不检查断言。这是您必须打开的额外标志。 +1 顺便说一句。
【解决方案2】:

您可以像这样使用泛型类类型来做到这一点:

private class ClassB <R extends ClassA & InterfaceI> {
    R mVaraible;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    相关资源
    最近更新 更多