在java中,我可以重用接口参数中的泛型类型来创建一个同样需要泛型类型的不同类吗?如果是,怎么做?

pbpqsu0x  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(278)

以下是我的java代码概述:

// An interface and an implementation class:
public interface MyInterface<T1, T2> { ... }
public class MyImplementation implements MyInterface<int, String> { ... }

// Another class
public class MyClass<T3, T4> { ... }

// Function I want to call
void doStuff(MyInterface i) {
  MyClass<int, String> n;
}

// I want to call the function like this:
MyInterface mi = new MyImplementation();
doStuff(mi);

我不知道的是我能不能 MyClass<int, String> n; 以某种方式使用 MyImplementation 传递给的类 doStuff() ? 在这种情况下, n 将自动使用 <int, String> 因为这就是 MyImplementation 使用。

i2byvkas

i2byvkas1#

是的,你可以。
让我们远离模糊不清的假设,去上真正的课: Collection<T> , Map<K, V> ,和 Function<F, T> . 假设您想在Map类型(或接口,无所谓,签名就是签名)中编写一个方法,它接受一个“键转换器”(一个将ks转换为其他东西的东西),返回其他东西的集合,该集合由Map中的每个键组成,通过转换器抛出,并添加到集合中。

class MapImpl<K, V> implements Map<K, V> {
    public <T> Collection<T> convertKeys(Function<K, T> converter) {
        List<T> out = new ArrayList<T>();
        for (K key : keySet()) out.add(converter.apply(key));
        return out;
    }
}

这里使用了很多概念:
实现没有锁定k和v的类型。您不只是从实现的接口继承typevars,因此,mapimpl获得自己的k,v,它也用作接口的k,v。包括1号线。
convertkeys方法除了已经得到的k,v之外,还引入了自己独特的typevar。那是因为。。这个方法就是这样工作的:Map的键有某种类型,值有其他类型,这个转换器转换成第三种类型。三种类型:k、v和t。一个方法可以为这个方法引入新的变量,这就是 <T> 都在第二行。
无论何时命名类型名,如果该类型已泛化,则必须 <> 然后放上合适的东西。或者不要放入适当的东西,这意味着:嘿,编译器,如果可以的话,找出它(所谓的菱形运算符)。在代码段中,使用 MyInterface i 作为方法param type,这很糟糕:myinterface有泛型,所以它必须有 <> 背后。在这种情况下,您必须添加一些内容,因为编译器无法尝试解决这些问题。
回到您的代码,它可能看起来像:

public <K, V> void doStuff(MyInterface<K, V> i) {
    MyClass<K, V> n;
}

注意:记住,泛型把事物联系起来。最后一个片段只是说:“i”参数类型的myinterface部分的第一个typearg和“n”局部变量的myclass部分的第一个typearg之间存在链接。我不知道那是什么类型的。我知道是同一种。泛型是完全无用的,除非typevar出现在2个或更多的地方。
nb2:如果你想得到真正的幻想,你就开始考虑共/反/不变性。例如,在关键转换器的故事,如果你有一个转换器,可以将任何对象转换成其他东西,这将是很酷的。事实上,一个可以转换ks或ks的任何超类型的转换器都是合适的。所以,真的,你最终会得到: public <T> Collection<T> convertKeys(Function<? super K, ? extends T> converter) {} -但是这种高级的差异工程是一个很好的奖励,请随意跳过源代码中的那些部分,直到您遇到麻烦,因为您没有考虑到它。

相关问题