Враховуючи загальний інтерфейс, такий як наступне
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] { ... }
...
}