2012-01-07 9 views
8

Dado el siguiente código:¿Por qué no es posible anular un tipo abstracto ya implementado?

class A { 

    class B 

    type C <: B 

    trait D 

} 

class E extends A { 

    type C = B 

} 

class F extends E { 

    override type C = B with D 

} 

¿Por qué compilador de presentación del IDE Scala dentro del IDE de Eclipse Indigo se quejan con el mensaje de error tipo C primordial en la clase E, que es igual a F.this.B; tipo C tiene tipo incompatible?

Después de todo, la clase "B" solo se "modifica" con el carácter "D" y, por lo tanto, las dos definiciones de tipo son del mismo tipo de base, que es "B". De ahí las definiciones de tipos compatibles.

El código debajo de funciona. Considero que las reglas para la asignación de tipo similar a la asignación de variables, tales como:

class Foo 

trait Bar 

val a: Foo = new Foo 

val fooWithBar: Foo = new Foo with Bar 

Tengo entendido mal?

+1

Foo with Bar es un subtipo de Foo. Este no es el problema. No se le permite redefinir un miembro de tipo mientras está fijo, incluso a un subtipo. Si tuviera la clase Bar extiende Foo, tampoco podría redefinir un miembro de tipo de Foo a Bar. –

Respuesta

13

No son compatibles, tipo C podría usarse en una posición contravariante

class E extends A { 
    type C = B 
    def f(c: C) 
} 


class F extends E { 
    override type C = B with D 
    def f(c: ???) 
} 

Complemento dado e: E, se le permite llamar e.f(new B). ¿Qué pasa si e fuera val e = new F?

+0

¿Por qué esta constelación debe ser incorrecta siempre que el tipo reemplazado "C" esté más restringido y mantenga su tipo base "B". Si el método "f" acepta "B" s ¿por qué no debería aceptar las subclases de este documento, según la redefinición "B con D" s? –

+3

Si el método acepta B, sin duda debe aceptar subtipos. El problema es que las instancias de F requerirán B con D y, por lo tanto, no aceptarán más simplemente B. Un subtipo de E debe aceptar B en f. Por supuesto, aceptará subtipos. No puede requerir que el argumento sea un subtipo. –

+0

No estoy seguro de que este sea el ejemplo de contador correcto. Aquí está el por qué: (lo siento, sin tener en cuenta, estaba tratando de presionar cancelar en mi teléfono, pero se publicó en su lugar ..) –

Cuestiones relacionadas