/ / Generics в Scala: реалізація інтерфейсу / ознаки двічі? - c #, java, generics, scala

Generics в Scala: реалізація інтерфейсу / ознаки двічі? - c #, java, generics, scala

Враховуючи загальний інтерфейс, такий як наступне

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

Я можу в C # створити клас, який реалізує я двічі (або більше) з різними типами, що поставляються для T, наприклад.

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

Це не може бути зроблено в Java через стирання загальної інформації про тип, але може щось подібне досягти в Scala?

Відповіді:

12 для відповіді № 1

Ні. Змішання в тому ж стилі можливо лише в Scala, якщо 2 типи, з якими ознака (інтерфейс) параметризується типом, який відповідати один одному і ознака не змішується в один і той же клас двічі безпосередньо. Щоб переконатися, що 2 типи відповідають один одному, вам, як правило, доведеться зробити параметр типу коваріантним (+)

Наприклад, це не допускається:

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]

Але це так:

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

Зауважте, що у цьому випадку ви не отримаєте перевантаження семантика, як це відбувається з C #, але переважаючий семантика - всі методи в Росії A з відповідним підписом буде злито в одному методі з самим специфічним підписом, вибравши метод відповідно до правила лінеаризації, а не один метод для кожного разу, коли ви змішували ознаку.


10 за відповідь № 2

Ні, це не може. Взагалі, що я роблю в цьому випадку

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