2013-10-03 18 views
16

Si consideri il codice qui sotto:In scala multipla ereditarietà, come risolvere i metodi in conflitto con la stessa firma ma con tipi di ritorno diversi?

trait A { 
    def work = { "x" } 
} 

trait B { 
    def work = { 1 } 
} 

class C extends A with B { 
    override def work = super[A].work 
} 

Classe C non compilerà in scala 2.10, a causa di "metodo di lavoro prevalente alla caratteristica di tipo A => Stringa; metodo di lavoro è di tipo incompatibile".

Come scegliere un metodo specifico?

risposta

15

Ho paura che non ci sia modo di farlo. Il modo super[A].work funziona solo se A e B hanno gli stessi tipi di ritorno.

Considerate questo:

class D extends B 

.... 

val test: List[B] = List(new C(), new D()) 
test.map(b => b.work) //oops - C returns a String, D returns an Int 
5

Scala semplicemente impedisce di mescolare A e B insieme se dichiarano un metodo con lo stesso nome e firma incompatibile.

6

Non si può farlo.

Guardate questo pezzo di codice:

val c = new C 
val a: A = c 
val b: B = c 

Non c'è modo che entrambi di queste righe potrebbe funzionare:

val s: String = a.work 
val i: Int = b.work 

Se abbiamo permesso tale codice per compilare, uno di questi gli incarichi avrebbero dovuto gettare un ClassCastException o fallire in un altro modo. Quindi, semplicemente non è possibile risolvere questo conflitto.

Credo che devi per risolvere questo con una qualche forma di delega, forse qualcosa di simile:

class C extends A { 
    def toB = new B { 
    //implement B methods by somehow delegating them to C instance 
    } 
} 
5

Non si può fare che in Scala.

Il modo di lavorare intorno a questo è quello di utilizzare i tratti come collaboratori

trait A { 
    def work = { "x" } 
} 

trait B { 
    def work = { 1 } 
} 

class C { 
    val a = new A { } 
    val b = new B { } 

    a.work 
    b.work 
} 
Problemi correlati