2016-10-21 6 views
0

Я определил черту Super[A] с одним абстрактным методом и несколькими конкретными методами, многие из которых просто создают экземпляр нового объекта с некоторыми изменениями. Это пример:Как продлить подпись типа Scala подклассам?

trait Super[A] { self => 

    def abstractMethod: A 

    def map[B](f: A => B): Super[B] = new Super[B] { 
    def abstractMethod = f(self.get) 
    } 
} 

теперь я хотел бы построить несколько классов, которые наследуют Super[A] без изменения типа возвращаемого каждого конкретного метода.

Какой самый идиоматический способ достичь такого результата?

+0

Если вы хотите для конкретного типа 'A', тогда вы можете сделать' class Impl extends Super [String] ', если вы хотите, чтобы реализация для некоторого общего type 'A' - вы можете сделать' class Impl [A] extends String [A] '. Я не знаю всей задачи, над которой вы работаете, но в качестве альтернативы вы можете рассмотреть класс. –

+0

Я смущен, почему вы хотите изменить типы возвращаемых данных. Не могли бы вы показать пример класса, который наследует от 'Super [A]', где вам (нужно) изменять тип возврата каждого конкретного метода? – TeWu

+0

Мне нужен каждый конкретный метод, чтобы вернуть экземпляр конкретного класса, а не экземпляр Super –

ответ

0

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

Примечание: .get не был определен, поэтому я использовал .abstractMethod в .map вместо

trait Super[A] { self => 
    def abstractMethod: A 

    def map[B](f: A => B) = new Super[B] { 
    def abstractMethod = f(self.abstractMethod) 
    } 
} 

несколько классов

class X(val n: Int) extends Super[X] { 
    def abstractMethod = this 
    def toY = new Y(n) 
} 

class Y(val n: Int) extends Super[Y] { 
    def abstractMethod = this 
    def toX = new X(n) 
} 

работает, как ожидалось

val x: X = new X(999) 
val y: Y = x.map(_.toY).abstractMethod 
val x2: X = y.map(_.toX).abstractMethod 

val sup_x: Super[X] =  x.map(_.abstractMethod) 
val sup_y: Super[Y] =  x.map(_.toY) 
val sup_y2: Super[Y] = sup_x.map(_.toY) 
val sup_x2: Super[X] = sup_y.map(_.toX) 
Смежные вопросы