首页 > 解决方案 > 在泛型类中使用类的子类型

问题描述

我正在尝试在另一个使用该类的类中使用类的泛型类型:

科特林

class Callback <O> () 

class Controller <E> (callback: E) where E: Callback<O> {
    fun foo1 (a: O) {...}
    fun foo2 (): O {...}
}

爪哇

class Callback <O> {}

class Controller <E extends Callback<O>> {
    Controller(E callback) {}
    public void foo1(O a) {...}
    public O foo2() {...}
}

一个简单的解决方案是以这种方式在 Controller 类上声明 E 和 O 类型:

科特林

class Controller <E, O> (callback: E) where E: Callback<O> { ... }

爪哇

class Controller <E extends Callback<O>, O> { ... }

但是,我想避免在构造函数上声明这两种类型,因为信息是重复的,而且不是那么漂亮。

编辑

我需要构造函数上的类型E,因为我需要定义函数,例如:

class StringCallback: Callback<String>() { ... }

fun example(callbackParam: Controller<StringCallback>) { ... }

我希望对象callbackParam使用我定义的StringCallback,而不是任何Callback<String>

并且记住,我还需要O类中的Controller类型来操作这种类型。我可以“提取”或“推断”它而不在通用构造函数中声明它吗?

[@LppEdd 征得您的同意,我将使用您的课程 :) ]

任何想法?

提前致谢!!

标签: javagenericskotlin

解决方案


你能做的是

class Controller<E> {
    private final Callback<E> callback;

    Controller(final Callback<E> callback) {
        this.callback = callback;
    }

    public void foo1(final E a) { callback.set(a); }
    public E foo2() { return callback.get(); }
}

例子:

final Controller<String> stringController = new Controller<>(new Callback<>());

那是因为你已经知道你会接受一个Callback<?>.
没有必要使用E extends Callback. 但请继续阅读

这个

Controller(final Callback<? extends E> callback)

意味着构造函数将接受作为子类型的每个类型Callback<E>

class StringCallback extends Callback<String> { ... }
class IntegerCallback extends Callback<Integer> { ... }

final Controller<String> c1 = new Controller<>(new StringCallback());
final Controller<Integer> c2 = new Controller<>(new IntegerCallback());

推荐阅读