Pass subclass of class as type parameter (type parameter is subclass)

553 Views Asked by At

let's consider:

public class Text extends BinaryComparable
    implements WritableComparable<BinaryComparable> {

We can see that Text is BinaryComparable.

Then, let's consider

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

I have some class in Scala:

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

It is not possible to create

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

due to type mismatch. Why? After all, Text is BinaryComparable How to resolve it?

2

There are 2 best solutions below

4
Dmytro Mitin On BEST ANSWER

You can try to add one more type parameter

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

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

On contrary to trait MyClass[A <: WritableComparable[_ >: A]] this doesn't produce illegal cyclic reference.

Alternatively you can define bounds in MyClass as

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

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

You can even exclude B with existential type (as @user proposed)

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

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

Such existential types will be deprecated in Scala 3

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

2
username On

WritableComparable[BinaryComparable] is not the same as or a supertype of WritableComparable[Text], as WritableComparable is invariant in T (Java generics doesn't really have covariance or contravariance).

If WritingComparable had been declared as trait WritingComparable[-A], then it would compile.

Your last code snippet does not make much sense, though, as MyClass does not take 2 type parameters (as Luis Miguel Mejia Suarez mentioned). You shouldn't get a type mismatch error, it should tell you you have too many parameters. I think you meant only MyClass[Text].

Here's a question asking about invariance, contravariance, and covariance.