Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-IsassignablefromParadox?_Java - Fatal编程技术网

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),对吗?)。