Java-IsassignablefromParadox?
我有一些第三方的课程。其精简功能(为了简洁起见)如下所示:Java-IsassignablefromParadox?,java,Java,我有一些第三方的课程。其精简功能(为了简洁起见)如下所示: // Third party code.. class ClassA implements InterfaceA { ... } class ClassB { ... } class WeirdCode { void registerUserMethod(func ...) { } void handle(Object input) { ... } } // My caller code.. function
// Third party code..
class ClassA implements InterfaceA { ... }
class ClassB { ... }
class WeirdCode {
void registerUserMethod(func ...) { }
void handle(Object input) { ... }
}
// My caller code..
function myHandler(T??? obj) {
// Do something with obj
}
WeirdCode weirdCode = new WeirdCode(...);
weirdCode.registerUserMethod(myHandler);
weirdCode.handle(new ClassA(...));
- 提供两类供外部使用的
和ClassA
。这些类中的每一个都与另一个完全无关(这意味着它们不共享一个共同的祖先)ClassB
- 具有一个
函数,该函数接受类型为handle()
的对象作为输入object
函数检查对象的类型是handle()
还是ClassA
ClassB
- 如果类型匹配,代码将使用相同的对象参数调用用户定义的函数
// Third party code..
class ClassA implements InterfaceA { ... }
class ClassB { ... }
class WeirdCode {
void registerUserMethod(func ...) { }
void handle(Object input) { ... }
}
// My caller code..
function myHandler(T??? obj) {
// Do something with obj
}
WeirdCode weirdCode = new WeirdCode(...);
weirdCode.registerUserMethod(myHandler);
weirdCode.handle(new ClassA(...));
通常,该类在同一时间只用于一种类型。因此,我可以使用ClassA
或ClassB
,但不能同时使用两者。但是,如果我想同时处理ClassA
和ClassB
对象,我必须这样做:
// My caller code..
function myHandlerA(ClassA obj) { ... }
function myHandlerB(ClassB obj) { ... }
WeirdCode weirdCodeA = new WeirdCode(...);
WeirdCode weirdCodeB = new WeirdCode(...);
weirdCodeA.register(myHandlerA);
weirdCodeB.register(myHandlerB);
weirdCodeA.handle(new ClassA(...));
weirdCodeB.handle(new ClassB(...));
我希望能够做到以下几点:
// My caller code..
function myHandlerAB(Object obj) { ... }
WeirdCode weirdCode = new WeirdCode(...);
weirdCode.handle(new ClassA(...));
weirdCode.handle(new ClassB(...));
但是,如果我这样做,WeirdCode
会抛出一个异常,因为其中包含以下代码:
void handle(Object obj) {
...
if (ClassA.class.isAssignableFrom(obj.getType())) {
...
myHandler(obj);
}
else if (ClassB.class.isAssignableFrom(obj.getType())) {
...
myHandler(obj);
}
else {
throw new Exception();
}
...
}
在整个图片中,我唯一能控制的是myHandler()
函数的原型。是否可以定义一个类型,使得ClassA
和ClassB
都可以从中赋值,以及ClassA
和ClassB
都可以向其强制转换?我认为这是不可能的。但我希望被证明是错的,因为这会帮助我解决问题
在整张照片中,我唯一能控制的就是原型
myHandler()函数的。是否可以定义这样的类型:
ClassA和ClassB以及ClassA都可以从中赋值
而B级演员能做到吗
所以你想做的是:
MyType myType1 = new ClassA(...);
MyType myType2 = new ClassB(...);
而且
ClassA clsA = (ClassA) myType1;
ClassB clsB = (ClassB) myType2;
准确吗
你的致命弱点是你不能控制ClassA和ClassB的类型。据我所知,这些对象是由您无法修改的第三方代码定义的。听起来您想要做的是提供一种有限的多重继承,它可以由接口继承提供。然而,由于您不控制这些类,所以这个解决方案是不可行的
尽管instanceof
操作符被嘲笑为良好的面向对象软件设计的祸根,但在这样的情况下,它是必不可少的,在这种情况下,您必须与其他人的代码进行互操作
FWIW,Java并不以通常理解的方式理解“原型”(例如JavaScript中的原型继承)。您不应该试图强迫Java理解原型继承。那太糟糕了。。对于java没有提供多重继承,我并不像第三方代码使用
isAssignableFrom
操作那样愤怒。。好吧,我想我可以忘记实现一个干净的、通用的解决方案,而不得不求助于一个脏的解决方案,沿着复制粘贴的路线=/随着时间的推移,Java获得了越来越多的多重继承。在Java8之前,唯一的多重继承是接口继承。Java8通过在接口中提供默认实现的能力引入了更多的多重继承。总的来说,在Java中限制完全多重继承的决定是一个好的决定。它可能避免了比它所造成的更多的问题。这个问题似乎可以通过适配器设计模式来解决。但是我不明白为什么句柄
方法会抛出异常。如果您的myHandlerAB
没有抛出异常,那么myHandlerAB
也不应该抛出异常(我假设缺少一个寄存器(myHandlerAB),对吗?)。