让我们有以下类层次结构:
public class ParentClass implements SomeInterface {
}
public class ChildClass extends ParentClass {
}
然后让我们有这两个实例:
ParentClass parent;
ChildClass child;
然后我们有以下TRUE语句
(parent instanceof SomeInterface) == true
(child instanceof SomeInterface) == true
是否可以在ChildClass中实现SomeInterface,所以当我们检查instanceof运算符时它返回false?
如果不可能,是否有解决方法?
答案 0 :(得分:18)
不,这是不可能的,你这样做的意图是一个很好的暗示,你的班级层次结构中存在某些缺陷。
解决方法:更改类层次结构,例如。像这样:
interface SomeInterface {}
abstract class AbstractParentClass {}
class ParentClass extends AbstractParentClass implements SomeInterface {}
class ChildClass extends AbstractParentClass {}
答案 1 :(得分:7)
也许组合而不是继承是你想要的,即拥有一个“基类”对象作为成员,只需实现你需要的接口,转发成员所需的任何方法。
答案 2 :(得分:3)
我同意其他答案,这在Java中是不可能的。
其他答案进一步表明它显示了您的设计中的缺陷。
虽然我同意他们的观点,但只是指出一些着名的OO专家(特别是Bertrand Meyer)不同意我们,并且相信应该允许这样的设计。
其他OO继承模型(尤其是Meyer的Eiffel编程语言)确实支持您正在寻找的“可用性或类型的更改”(CAT)功能。
答案 3 :(得分:2)
这是不可能的,这样做会违反ChildClass和ParentClass之间隐含的IS-A关系。你为什么要这样做?
答案 4 :(得分:2)
我认为你不能“实现”它,但你可以检查它是否是父类的实例。你的界面是你的吗?如果是这样,你可以扩展它以包含一个带有语义的“IsObjectDerived”方法,如果该类只派生自object,则返回true。由于您正在编写类,所以您需要做的就是在父类中实现它,如果对象是Parent类,则返回true,否则返回false。
您也可以通过检查当前类的超类并确保它是对象来进行反射。我可能会这样做,因为那时实现类不能说谎。您可能希望在我找到的Java中查看tutorial反射。
[编辑]一般来说,我同意在合理的设计中这似乎是不必要的,但可以做到。
答案 5 :(得分:1)
由于继承,OOP多态性的基础,表示is-A关系 - 您的问题似乎要求重新定义“是”关系是“不是”关系。
那不行。
回到一些介绍性的面向对象文本或在线资料,研究面向对象的意思:多态,封装和身份。
如果您想要这样的情况,请在“C”中编程。不要假装使用OOP语言功能编写OOP代码。只需使用struct来保存您的数据。到处都是工会。放弃使用类型转换。
您的程序可能无法可靠地运行,但您将能够绕过Java和C ++引入的任何限制语言,使程序更可靠,更易于阅读,更易于编写/修改。
在像SmalTalk或Python这样的动态编程语言中,你可以在运行时将蝴蝶翅膀从翅膀上撕掉。但只能通过改变/破坏对象的类型。
这样做不会给你买任何东西。有编码/设计技巧和设计模式可以让你完成任何与之相似的“好”结果。
最好是考虑一下你在应用程序中想要做什么,然后尝试使用声音技术找到最安全/最简单的方法。
答案 6 :(得分:0)
我认为你应该把这个问题作为你的界面和类设计存在缺陷的明确迹象。即使你可以用Java做(而且我认为你不能),你也不应该这样做。
如何重新分解ParentClass,以便将SomeInterface实现与ChildClass中所需的实现分开。也许你需要ParentClass和ChildClass的公共基类。
答案 7 :(得分:0)
我没有看到这将是什么样的练习,但你可以使用Shigeru Chiba等人创建的优秀包Javassist动态地改变一个类。使用它,您可以在类中添加和删除功能,然后使用这些类的实例而不保存为类文件。
动态,有趣,让任何人都感到困惑。小心使用是我的建议,但请尽量使用它,因为在我看来它会让你成为一个更好的程序员。
(我相信ASM以类似的方式工作,但到目前为止我还没有尝试过。在JVM上工作的非java语言创建者似乎非常受欢迎,所以它可能很好。)
答案 8 :(得分:-1)
也许你有一个特定的案例可以设计出更好的解决方案,但对于一般情况你需要一些黑魔法。最终Javassist可以用来“破解”你的对象,但我不太确定。