以下是我的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
使用。
1条答案
按热度按时间i2byvkas1#
是的,你可以。
让我们远离模糊不清的假设,去上真正的课:
Collection<T>
,Map<K, V>
,和Function<F, T>
. 假设您想在Map类型(或接口,无所谓,签名就是签名)中编写一个方法,它接受一个“键转换器”(一个将ks转换为其他东西的东西),返回其他东西的集合,该集合由Map中的每个键组成,通过转换器抛出,并添加到集合中。这里使用了很多概念:
实现没有锁定k和v的类型。您不只是从实现的接口继承typevars,因此,mapimpl获得自己的k,v,它也用作接口的k,v。包括1号线。
convertkeys方法除了已经得到的k,v之外,还引入了自己独特的typevar。那是因为。。这个方法就是这样工作的:Map的键有某种类型,值有其他类型,这个转换器转换成第三种类型。三种类型:k、v和t。一个方法可以为这个方法引入新的变量,这就是
<T>
都在第二行。无论何时命名类型名,如果该类型已泛化,则必须
<>
然后放上合适的东西。或者不要放入适当的东西,这意味着:嘿,编译器,如果可以的话,找出它(所谓的菱形运算符)。在代码段中,使用MyInterface i
作为方法param type,这很糟糕:myinterface有泛型,所以它必须有<>
背后。在这种情况下,您必须添加一些内容,因为编译器无法尝试解决这些问题。回到您的代码,它可能看起来像:
注意:记住,泛型把事物联系起来。最后一个片段只是说:“i”参数类型的myinterface部分的第一个typearg和“n”局部变量的myclass部分的第一个typearg之间存在链接。我不知道那是什么类型的。我知道是同一种。泛型是完全无用的,除非typevar出现在2个或更多的地方。
nb2:如果你想得到真正的幻想,你就开始考虑共/反/不变性。例如,在关键转换器的故事,如果你有一个转换器,可以将任何对象转换成其他东西,这将是很酷的。事实上,一个可以转换ks或ks的任何超类型的转换器都是合适的。所以,真的,你最终会得到:
public <T> Collection<T> convertKeys(Function<? super K, ? extends T> converter) {}
-但是这种高级的差异工程是一个很好的奖励,请随意跳过源代码中的那些部分,直到您遇到麻烦,因为您没有考虑到它。