Внутренний класс с верхней границей

Я хотел бы создать универсальный класс с параметром типа T, который затем создает экземпляры внутреннего класса, обертывающие значения типа T. Я подумал, что если бы я использовал верхнюю границу, чтобы сказать, что T должен быть подтипом, например. String, я смогу создавать экземпляры внутреннего класса, инициализированного с помощью String.

class Test[T <: String] {

    private class TestEntry(val value: T)

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

Но я получаю следующую ошибку:

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

На самом деле, для моей цели можно было бы опустить верхнюю границу и вызвать new TestEntry(null), но компилятор даже не принимает null.

Что мне не хватает?

Изменить:

Позвольте мне перефразировать мой пример, мне нужно что-то вроде этого: я должен иметь возможность протестировать абстрактный сервис роскошных автомобилей с любым конкретным автомобилем без необходимости повторной реализации метода тестирования. Таким образом, и абстрактный класс (или трейт), и методы должны работать с подклассами роскошных автомобилей.

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]

person Zoltán Balázs    schedule 07.02.2012    source источник
comment
Предположим, что метод тестирования, который вы вызываете, - это testWithCar, я не понимаю, почему вы ожидаете, что Mercedes должен быть принят LuxuryCarService [Ferrari] в testWithARandomLuxuryCar, точно такая же проблема, как и в ответе @Rex Kerr.   -  person Didier Dupont    schedule 07.02.2012


Ответы (4)


Вы сказали, что T является подклассом String. Затем вы поворачиваетесь и пытаетесь присвоить ему строку! Это не сработает, как и это:

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!

Я не уверен, что вы на самом деле подразумеваете под кодом, но то, что вы написали, не должно (и не работает, как вы узнали) работать.

person Rex Kerr    schedule 07.02.2012
comment
Спасибо, добавил более конкретный пример (который тоже не работает, но не знаю как исправить). - person Zoltán Balázs; 07.02.2012

Отпустите параметр типа. Объявляйте вещи как LuxuryCar вместо CarType. Как вы думаете, зачем здесь нужен параметр типа?

person Daniel C. Sobral    schedule 07.02.2012

Я должен быть в состоянии протестировать абстрактный сервис роскошных автомобилей с любым конкретным автомобилем без необходимости повторной реализации метода тестирования.

Тогда вот что должен сказать тип:

def testWithCar(car: Car): Unit = {} // or LuxuryCar if you meant "with any specific luxury car"
person Alexey Romanov    schedule 07.02.2012

Скорее всего, я что-то упускаю, но... зачем вообще использовать дженерик? Другими словами, почему бы и нет

trait LuxuryCarService[LuxuryCar]

person Ed Staub    schedule 07.02.2012