0

I'd like to create a generic class with type parameter T which then creates instances of an inner class wrapping values of type T. I thought that if I used upper bound to tell that T must be subtype of eg. String, I'll be able to create instances of the inner class initialized with a String.

class Test[T <: String] {

    private class TestEntry(val value: T)

    def init: Unit = {
        new TestEntry("")
    }
}

But I get the following error:

<console>:12: error: type mismatch;
 found   : java.lang.String("")
 required: T
               new TestEntry("")
                         ^

Actually, for my purpose, it would do to omit the upper bound and call new TestEntry(null), but the compiler does not even accept null.

What am I missing?

Edit:

Let me rephrase my example, I need something like this: I should be able to test an abstract luxury car service with any specific car without the need to re-implement the testing method. So both the abstract class (or trait) and the methods should work on subclasses of luxury cars.

class Car
class LuxuryCar extends Car
class Mercedes extends LuxuryCar
class Ferrari extends LuxuryCar

trait LuxuryCarService[CarType <: LuxuryCar] {

    def testWithCar(car: CarType): Unit = {}

    def testWithARandomLuxuryCar: Unit = test(new Mercedes)

    def testWithNoCar: Unit = test(null)
}

trait MercedesCarService extends LuxuryCarService[Mercedes]
Zoltán Balázs
  • 157
  • 1
  • 8
  • Supposing that the test method you call is testWithCar, I don't see why you expect a Mercedes should be accepted by a LuxuryCarService[Ferrari] in testWithARandomLuxuryCar, exact same problem as in @Rex Kerr's answer. – Didier Dupont Feb 07 '12 at 17:21

4 Answers4

5

You've told it that T is a subclass of String. You then turn around and try to assign a string to it! That isn't going to work, any more than this will:

class Car {}
class Mercedes extends Car {}         // Mercedes <: Car (T could be Mercedes)
def serviceLuxuryCar(m: Mercedes) {}  // This is like your TestEntry
serviceLuxuryCar(new Car)             // This won't work, it's not a Mercedes!

I'm not sure what you actually mean for the code to do, but what you wrote should not (and does not, as you've found out) work.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
2

Let go of the type parameter. Declare stuff as LuxuryCar instead of CarType. Why do you think you need a type parameter here?

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
0

I should be able to test an abstract luxury car service with any specific car without the need to re-implement the testing method.

Then that's what the type should say:

def testWithCar(car: Car): Unit = {} // or LuxuryCar if you meant "with any specific luxury car"
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
0

Chances are I'm missing something, but... why use a generic here at all? In other words, why not

trait LuxuryCarService[LuxuryCar]

Ed Staub
  • 15,480
  • 3
  • 61
  • 91