我有一些第三方课程。它的简化(为了简洁起见)功能如下:
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
都可以从中分配,以及 var lib = {
func: function(foo) { return 1+foo; }
};
lib.func.bar = 10;
lib.func.bar2 = function() { return this(this.bar); };
// current behavior: lib.func.bar2() returns 11
// needed behavior: lib.func.bar2() to return 12, without changing bar2()
和func
都可以转换为它?我认为这是不可能的。但我希望被证明是错的,因为它会帮助我解决我的问题。
答案 0 :(得分:1)
我在这整张照片中唯一可以控制的就是原型 myHandler()函数。是否可以定义这样的类型 ClassA和ClassB都可以从它分配,也可以分配给ClassA 和ClassB可以投射吗?
所以你想要做的是:
MyType myType1 = new ClassA(...);
MyType myType2 = new ClassB(...);
和...
ClassA clsA = (ClassA) myType1;
ClassB clsB = (ClassB) myType2;
准确吗?
你的阿喀琉斯之踵是你无法控制ClassA和ClassB的类型。据我了解,这些对象是由您无法修改的第三方代码定义的。听起来你想要做的是提供一种有限的多重继承形式,可以通过接口继承提供。但是,由于您不控制这些类别,因此该解决方案不可行。
尽管instanceof
运算符被嘲笑为良好的面向对象软件设计的祸害,但对于必须与其他人的代码进行互操作的情况,这是必不可少的。
FWIW,Java不会以通常理解的方式理解“原型”(例如,JavaScript中的原型继承)。你不应该试图强迫Java理解原型继承。