通过谷歌搜索协变和逆变,您可能会找到一些有关更复杂类型的有用信息。
如果你不介意使用 Scala,它可以编译成字节码,你可以在 Java 程序中使用,Scala 为你提供了一些很好的语法来做这种事情(Java 稍后):
水果类
类篮子[T <:水果] {
def addToBasket(水果:T) = {}
}
苹果类扩展水果
柠檬类扩展水果
类 AppleBasket 扩展了 Basket[Apple]
val applebasket = 新的 AppleBasket
applebasket.addToBasket(新苹果)
applebasket.addToBasket(新柠檬)
此代码片段的最后一行给出了编译时错误:
$ scala 测试.scala
C:\cygwin\home\user\Test.scala:18: 错误:类型不匹配;
发现:this.Lemon
必需:this.Apple
applebasket.addToBasket(新柠檬)
^
发现一个错误
我最近一直在玩 Scala,我在 Java 中思考这个问题时遇到了麻烦,但在 Java 中我可能会做更多这样的事情:
类水果{}
Apple 类扩展 Fruit{}
柠檬类扩展水果{}
类篮子<T扩展水果>{
公共无效 addToBasket(T foo) {}
}
类废话{
无效 doIt() {
苹果 a = 新苹果();
篮子 b = 新篮子<苹果>();
b.addToBasket(a);
柠檬 l = 新柠檬();
b.addToBasket(l);
}
}
b.addToBasket(l) 行给出以下编译时类型错误:
Basket<Apple> 类型中的方法 addToBasket(Apple) 不适用于参数 (Lemon)
给出相同编译错误的另一个选项(从注释中复制以使其更清晰):
//水果、苹果和篮子的定义相同,但有:
类 AppleBasket 扩展 Basket<Apple> {}
类废话{
无效 doIt() {
苹果 a = 新苹果();
篮子<Apple> b = new AppleBasket();
b.addToBasket(a);
柠檬 l = 新柠檬();
b.addToBasket(l);
}
}