2011-09-27 27 views
12

dieron una interfaz genérica como la siguienteGenéricos en Scala: implementar una interfaz/rasgo dos veces?

interface I<T> { 
    void m(T t); 
} 

que pueda en C# crear una clase que implementa I dos veces (o más) con diferentes tipos suministrados por T, por ejemplo,

class C : I<int>, I<String> { 
    public void m(int i) { } 
    public void m(String s) { } 
} 

Esto no se puede hacer en Java debido a la eliminación de la información de tipo genérico, pero es posible que algo como esto se logrará en Scala?

+0

Puede describir en el código Scala lo que desea hacer. Mucha gente aquí no está familiarizada con C#. – Jus12

+0

Bueno, no estoy muy familiarizado con Scala (tratando de aprender :)). Sin embargo, el código anterior debe ser fácil de entender para cualquier persona que conozca Java, siempre que sepa que ":" después de "clase C" en esta configuración significa "implementa" en Java-speak. Lo que he intentado en Scala es convertirlo en un rasgo (simplemente reemplazar "interfaz" por "rasgo"), y luego definir C como "la clase C se extiende I con I {...", pero eso no funciona . – Eyvind

+0

En Scala Los tipos genéricos están encerrados en '[]', por lo que haría esto como 'I [Int]' y 'I [String]'. ¿Has intentado usar 'ClassManifest' en la declaración? – Jus12

Respuesta

12

No. de mezclado en el mismo rasgo sólo es posible en Scala si los 2 tipos con la que el rasgo (interfaz) es parametrizada con tipos que conforman entre sí y el rasgo no se mezcla en la misma clase dos veces directamente. Para garantizar que los 2 tipos se ajusten entre sí, generalmente deberá hacer que el parámetro de tipo sea covariante (+).

Por ejemplo, esto no está permitido:

scala> trait A[+T] { def foo: T = sys.error() } 
defined trait A 

scala> class C extends A[AnyRef] with A[String] 
<console>:8: error: trait A is inherited twice 
     class C extends A[AnyRef] with A[String] 

Pero esto es:

scala> trait A[+T] { def foo: T = sys.error() } 
defined trait A 

scala> class C extends A[AnyRef] 
defined class C 

scala> class B extends C with A[String] 
defined class B 

Tenga en cuenta que en este caso no obtener el sobrecargando semántica como es el caso con C# , pero la semántica anulando - todos los métodos en A con la firma correspondiente se fusionarán en un método con la firma más específica, eligiendo el método d de acuerdo con linearization rules, en lugar de tener un método para cada vez que mezcle el rasgo.

10

No, no puede. Generalmente lo que hago en este caso es

class C { 
    object IInt extends I[Int] { ... } 
    object IString extends I[String] { ... } 
    ... 
}