代码之家  ›  专栏  ›  技术社区  ›  m_pGladiator

是否可以在Java中实现派生类中的接口?

  •  2
  • m_pGladiator  · 技术社区  · 17 年前

    让我们有以下类层次结构:

    public class ParentClass implements SomeInterface {
    }
    
    public class ChildClass extends ParentClass {
    }
    

    那么让我们来看看这两个例子:

    ParentClass parent;
    ChildClass child;
    

    那么我们有以下真实的陈述

    (parent instanceof SomeInterface) == true
    (child instanceof SomeInterface) == true
    

    是否可以在childClass中取消SomeInterface,所以当我们检查instanceOf运算符时,它返回false?

    如果不可能,是否有解决方法?

    9 回复  |  直到 17 年前
        1
  •  18
  •   user28205    17 年前

    不,这是不可能的,并且您这样做的意图是一个很好的提示,说明您的类层次结构中存在缺陷。

    解决方法:更改类层次结构,例如:

    interface SomeInterface {}
    abstract class AbstractParentClass {}
    class ParentClass extends AbstractParentClass implements SomeInterface {}
    class ChildClass extends AbstractParentClass {}
    
        2
  •  7
  •   OregonGhost    17 年前

    也许组合而不是继承是您想要的,也就是说,将一个“基类”对象作为成员,并且只实现您需要的接口,将任何需要的方法转发给成员。

        3
  •  3
  •   Oddthinking    17 年前

    我同意在Java中不可能的其他答案。

    其他的答案进一步表明它在你的设计中显示了一个缺陷。

    虽然我同意他们的观点,但我只是公平地指出,一些著名的OO专家(尤其是Bertrand Meyer)不同意我们的观点,并认为应该允许这样的设计。

    其他OO继承模型(特别是Meyer的Eiffel编程语言)确实支持您正在寻找的“可用性或类型更改”(cat)特性。

        4
  •  2
  •   C. K. Young    17 年前

    这是不可能的,这样做会违反隐含的IS——儿童阶级和家长阶级之间的关系。你为什么要这样做?

        5
  •  2
  •   tvanfosson    17 年前

    我认为您不能“不加修饰”它,但您可以检查它是否是父类的实例。接口是你的吗?如果是这样,您可以扩展它以包含一个语义为“isObjectDerived”的方法,如果类只从对象派生,则返回true。因为您正在编写类,所以只需在父类中实现它,如果对象是类父对象,则返回true,否则返回false。

    通过检查当前类的超类并确保它是对象,您还可以对反射进行此操作。我可能会这样做,因为实现类不会说谎。你可能想看看 tutorial 我发现Java中的反射。

    [编辑]总的来说,我同意在合理的设计中这似乎是不必要的,但可以做到。

        6
  •  1
  •   JohnnySoftware    17 年前

    由于OOP多态性的基础是继承,它表示一种IS—A关系—您的问题似乎请求一种方法来重新定义“IS”关系为“IS”关系为“IS—NOT”关系。

    那不行。

    回到一些介绍性的面向对象的文本或在线材料,研究面向对象的含义:多态性、封装和标识。

    1. 去掉身份,你就得到了COM/ActiveX和被盗的凭证。
    2. 去掉封装,没有人是安全的。
    3. 去掉复调的类型规则,你基本上什么都没有,这就是它所说的。

    如果你想要这样的情况,那么用“c”编程。不要乱来,假装用OOP语言特性编写OOP代码。只需使用结构来保存数据。让工会无处不在。放弃使用打字。

    您的程序可能不会可靠地工作,但您将能够绕过任何限制,如Java和C++语言,使程序更可靠,更容易阅读,更容易编写/修改。

    在像smaltalk或python这样的动态编程语言中,基本上可以在运行时撕掉蝴蝶的翅膀。但只能通过更改/破坏对象的类型。

    这样做不会给你带来任何好处。有一些编码/设计技术和设计模式可以让您在完成之后获得任何“好”的结果,这与此类似。

    最好的方法是,你想一想你在你的应用程序中到底要做什么,然后试着用合理的技术找到最安全/最简单的方法来完成它。

        7
  •  0
  •   Simon    17 年前

    我认为您应该把这个问题作为一个明确的迹象,表明您的接口和类设计有缺陷。即使你可以用Java做(我认为你不能),你也不应该这样做。

    如何重新分解parentclass,使someInterface实现独立于childclass中需要的实现。也许您需要一个用于ParentClass和ChildClass的公共基类。

        8
  •  0
  •   Anders Björklund    17 年前

    我不明白这是怎样的练习,但是你 能够 使用Shigeru Chiba等人创建的优秀包Javassist动态地更改类。使用它,您可以从类中添加和删除特性,然后使用这些类的实例而不另存为类文件。

    对其他人来说,充满活力、有趣且完全令人困惑。小心使用是我的建议,但是一定要好好玩玩它,因为它在我看来会让你成为一个更好的程序员。

    (我相信ASM也有类似的工作方式,但到目前为止我还没有尝试过。它似乎是非常流行的AMAM非Java语言创建者在JVM上工作,所以它可能是好的。

        9
  •  -1
  •   activout.se    17 年前

    也许你有一个特定的案例,可以设计出更好的解决方案,但是对于一般的案例,你需要一些黑色魔法。最终 Javassist 可以用来“黑客”你的物品,但我不太确定。