2017-02-07 5 views
1

Вот моя проблема.Scala предоставляет информацию о типе в подклассах общей функции

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

Некоторые псевдо-коды того, на что я нацеливаюсь.

abstract class A { 
    def foo[T](t: T): T 
} 

class B() extends A { 
    override foo[Int](t: Int): Int = t + 1 
} 

class C() extends A { 
    override foo[Double](t: Double): Double = t + 1.0 
} 

Как передать информацию о типе в подклассу? Я посмотрел на подобные проблемы. Они обращаются к этим типам, типам классов и абстрактным типам.

Благодаря

ответ

2

Как вы сказали, это абстрактный тип на A может решить, что:

abstract class A { 
    type T 
    def foo(t: T): T 
} 

class B extends A { 
    override type T = Int 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A { 
    override type T = Double 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

Если я пытаюсь работать с функцией foo извне и передать ей что-то вроде 'foo (t)' где t определяется как 'T <: A', я получаю' несоответствие типов; ожидаемый t.T; фактический T' – zaxme

+0

Что значит «пройти снаружи»? Вы должны определить тип при создании экземпляра 'B' и' C'. –

+0

класса 'D [Т <: А] { Защита ли (т: Т): Т = { t.foo (т) } }' – zaxme

1

насчет "параметрирования" на абстрактном классе:

abstract class A[T] { 
    def foo(t: T): T 
} 

class B extends A[Int] { 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A[Double] { 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

Извините, но, как я уже сказал, я не хочу параметризовать мой класс с причиной типа некоторых подклассов позже. – zaxme

+0

Ah OK, справедливо, я пропустил это (но я не вижу, как это может создать «проблемы подкласса») –

1

Ваш A особенно перспективно, что его можно назвать любымT. Поэтому любой тип, который его расширяет, должен выполнить это обещание.

val a: A = ... 
val x = a.foo("a") // calls foo[String] 
val y = a.foo(1) // calls foo[Int] 

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