将类的子类作为类型参数传递类型参数是子类

问题描述

让我们考虑一下

public class Text extends BinaryComparable
    implements WritableComparable<BinaryComparable> {

我们可以看到Text BinaryComparable

然后,让我们考虑

@InterfaceAudience.Public
@InterfaceStability.Stable
public interface WritableComparable<T> extends Writable,Comparable<T> {

我在Scala上过课:

trait MyClass[A <: WritableComparable[A]] {

无法创建

MyClass[Text] = new MyClass[Text]()

由于类型不匹配。为什么?毕竟,TextBinaryComparable解决方法

解决方法

WritableComparable[BinaryComparable]WritableComparable[Text]相同或不是WritableComparable的超类型,因为TWritingComparable中是不变的(Java泛型实际上并没有协变或相反)。

如果将trait WritingComparable[-A]声明为MyClass,则它将compile

不过,您的最后一个代码段没有多大意义,因为MyClass[Text]不接受2个类型参数(如Luis Miguel Mejia Suarez所述)。您不应该收到类型不匹配错误,它应该告诉您参数太多。我认为您的意思只是{{1}}。

Here是一个问题,询问不变性,协变和协方差。

,

您可以尝试再添加一个类型参数

trait MyClass[B >: A,A <: WritableComparable[B]]

val mc: MyClass[BinaryComparable,Text] = new MyClass[BinaryComparable,Text] {}

trait MyClass[A <: WritableComparable[_ >: A]]相反,它不会产生illegal cyclic reference

或者,您可以将MyClass中的范围定义为

trait MyClass[B,A <: B with WritableComparable[B]]

val mc: MyClass[BinaryComparable,Text] {}

您甚至可以排除存在类型(根据 @user 的建议)的B

trait MyClass[A <: B with WritableComparable[B] forSome { type B }]

val mc: MyClass[Text] = new MyClass[Text] {}

Scala 3中将弃用这种存在类型

http://dotty.epfl.ch/docs/reference/dropped-features/existential-types.html