studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones scala override traits

scala - para - manual de programacion android pdf



¿Por qué una clase no puede extender rasgos con un método de la misma firma? (5)

Este es el problema del diamante ¿Qué método debería heredarse, el de A o el de B? Puede evitar esto como sugirió Don, al usar un rasgo base común.

¿Por qué es el error a continuación? ¿Cómo solucionarlo?

EDITAR: Supuse que como A y B se compilan para pares de (interfaz, clase), es una cuestión de elegir la llamada al método estático correcto para implementar al compilar C. Esperaría que la prioridad fuera según el orden.

scala> trait A {def hi = println("A")} defined trait A scala> trait B {def hi = println("B")} defined trait B scala> class C extends B with A :6: error: error overriding method hi in trait B of type => Unit; method hi in trait A of type => Unit needs `override'' modifier class C extends B with A scala> trait A {override def hi = println("A")} :4: error: method hi overrides nothing trait A {override def hi = println("A")}

EDITAR: tenga en cuenta que en Ruby esto funciona bien:

>> module B; def hi; puts ''B''; end; end => nil >> module A; def hi; puts ''A''; end; end => nil >> class C; include A; include B; end => C >> c = C.new => # >> c.hi B => nil


Puede usar un rasgo base común, por ejemplo Base , de la siguiente manera:

trait Base {def hi: Unit} trait A extends Base {override def hi = println("A")} trait B extends Base {override def hi = println("B")} class C extends A with B

Con la jerarquía de tipos, el resultado de llamar a hi es el siguiente (tenga en cuenta el uso de {} para crear instancias de los rasgos):

scala> (new A {}).hi A scala> (new B {}).hi B scala> (new C).hi B


Tuve el mismo problema y no me gustó tener que crear un rasgo de intermediario porque puedo tener 4,5 o incluso 6 rasgos con los mismos métodos, porque son rasgos que contienen operaciones CRUD (buscar, crear ...). Además, necesitaba usar esos rasgos juntos solo para fines de prueba y siempre trato de evitar tanto como sea posible modificar la estructura de mi proyecto solo para facilitar mi prueba. Así que simplemente implementé esos rasgos en diferentes objetos:

class somethingToTest { object AImpl extends ATrait object BImpl extends BTrait val a = AImpl.methodDuplicated() val b = BImpl.methodDuplicated() }

Probablemente no sea la forma más inteligente de usar rasgos, pero no requiere ningún cambio en el código del proyecto, solo implica tener un poco más de código en las pruebas.


Un rasgo agrega métodos a la clase que lo mezcla. Si dos rasgos agregan el mismo método, la clase terminaría con dos métodos idénticos, que, por supuesto, no pueden suceder.

Si el método es privado en el rasgo, sin embargo, no causará problemas. Y si desea que los métodos se acumulen uno sobre el otro, puede definir un rasgo base y luego abstract override el abstract override de los rasgos heredados. Sin embargo, requiere una clase para definir el método. Aquí hay un ejemplo de esto:

scala> trait Hi { def hi: Unit } defined trait Hi scala> trait A extends Hi { abstract override def hi = { println("A"); super.hi } } defined trait A scala> trait B extends Hi { abstract override def hi = { println("B"); super.hi } } defined trait B scala> class NoHi extends Hi { def hi = () } defined class NoHi scala> class C extends NoHi with B with A defined class C scala> new C().hi A B

Sin embargo, si realmente quieres dos métodos separados para cada rasgo, entonces necesitarás componer en lugar de heredar .


Esto funciona para mí en 2.8 y 2.11, y te permitiría no ser intrusivo en los rasgos A o B :

trait A { def hi = println("A") } trait B { def hi = println("B") } class C extends A with B { override def hi = super[B].hi def howdy = super[A].hi // if you still want A#hi available } object App extends Application { (new C).hi // prints "B" }