2014-06-10 12 views
6

Mam klasę Scala, która próbuje zaimplementować interfejs Java (EntityManager w JavaEE 7 dla celów testów jednostkowych). Interfejs ma tych dwóch metod (między innymi):Jak zaimplementować interfejs Java w Scali z wieloma metodami zmiennych parametrów (typ gumki)?

public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses); 
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings); 

w realizacji Scala mam:

override def createStoredProcedureQuery(procedureName: String, resultClasses: Class[_]*): StoredProcedureQuery = ??? 
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ??? 

Jednak pojawia się następujący błąd:

MyTest.scala:134: error: double definition: 
method createStoredProcedureQuery:(procedureName: String, resultSetMappings: String*)javax.persistence.StoredProcedureQuery and 
method createStoredProcedureQuery:(procedureName: String, resultClasses: Class[_]*)javax.persistence.StoredProcedureQuery at line 133 
have same type after erasure: (procedureName: String, resultSetMappings: Seq)javax.persistence.StoredProcedureQuery 
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ??? 

nie mam udało się wymyślić pracę. Moje wyszukiwania w Google również nie udało się znaleźć i odpowiedzieć. Używam Scala 2.10.4.

Odpowiedz

2

AFAIK the EntityManager Interfejs Java nie może być zaimplementowany bezpośrednio w Scali. Warianty Java są konwertowane na Seq[Class[_]] w pierwszej metodzie i Seq[String] w drugiej metodzie. Ze względu na wymazanie obie metody mają wówczas ten sam podpis: createStoredProcedureQuery(String, Seq[_]).

Mogę tylko zaproponować obejście tego problemu. Powinieneś napisać abstrakcyjne klasy Java, który rozszerza interfejs EntityManager i wdrożenie metody naruszające 2 delegując do 2 innych abstrakcyjnych metod z różnymi nazwami w celu disambiguate:

public abstract class EntityManagerWorkaround implements EntityManager { 
@Override 
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) { 
    return createStoredProcedureQueryForResultClasses(procedureName, resultClasses); 
} 

@Override 
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) { 
    return createStoredProcedureQueryForResultSetMappings(procedureName, resultSetMappings); 
} 

public abstract StoredProcedureQuery createStoredProcedureQueryForResultClasses(String procedureName, Class... resultClasses); 

public abstract StoredProcedureQuery createStoredProcedureQueryForResultSetMappings(String procedureName, String... resultSetMappings); 

}

Teraz można przedłużyć klasa abstrakcyjna od Scala i implementacja ujednoznacznionych metod:

class EntityManagerImpl extends EntityManagerWorkaround { 
    override def createStoredProcedureQueryForResultClasses(procedureName: String, resultClasses: Class[_]*) = ??? 

    override def createStoredProcedureQueryForResultSetMappings(procedureName: String, resultSetMappings: String*) = ??? 
} 
+0

Dzięki. To zadziałało. Czy to oznacza, że ​​w języku jest "dziura"? Jeśli Scala ma współpracować z Javą, wygląda na to, że powinna obsługiwać Javę varargs (oprócz lepszych Scala varargs). – Integrator

+0

Problem nie dotyczy samych varargs, ale interakcji między varargs a przeciążaniem metod. Java ma skomplikowane reguły, które zostały zakodowane na kompilatorze, aby rozwiązać niejasności. Rozumiem, że projektanci Scali zdecydowali, że mają lepsze rzeczy do roboty, niż ponowne wdrożenie tych reguł w kompilatorze Scali ... Tak, tak, Scala ma pewne części, w których nie jest kompatybilna z Javą i nadal musimy wracać do Javy, aby działać wokół tych ograniczeń. – Jelmo

Powiązane problemy