あなたについて、後に(それ以上とtrait B
を書き換えることができます目標は少し違うと思います)
trait B extends A {
type MyType <: BInner with AInner
}
これは完全に意味があります。タイプB#MyType
の値は、BInner
またはAInner
と見なすことができます。
A
はすでにAbstract
のサブクラスであるため、Abstract
を繰り返す必要はありません。これは型宣言のために暗黙的であるため、override
を書く必要はありません。ですから、A#MyType
がAInner
として機能していないのはなぜですか?
ここでは、揮発性タイプについてのスカラー言語の仕様について説明します。仕様で言及
3.6 Volatile Types
Type volatility approximates the possibility that a type parameter or abstract type instance of a type does not have any non-null values. As explained in (§3.1), a value member of a volatile type cannot appear in a path. A type is volatile if it falls into one of four categories: A compound type T1 with ... with Tn {R } is volatile if one of the following two conditions hold. 1. One of T2, ..., Tn is a type parameter or abstract type, or 2. T1 is an abstract type and and either the refinement R or a type Tj for j > 1 contributes an abstract member to the compound type, or 3. one of T1, ..., Tn is a singleton type. Here, a type S contributes an abstract member to a type T if S contains an abstract member that is also a member of T . A refinement R contributes an abstract member to a type T if R contains an abstract declaration which is also a member of T . A type designator is volatile if it is an alias of a volatile type, or if it designates a type parameter or abstract type that has a volatile type as its upper bound. A singleton type p.type is volatile, if the underlying type of path p is volatile. An existential type T forSome {Q } is volatile if T is volatile.
その他の重要な項目は、抽象型のオーバーライドについてです:
Another restriction applies to abstract type members: An abstract type member with a volatile type (§3.6) as its upper bound may not override an abstract type member which does not have a volatile upper bound.
コンパイルエラーがある:
error: overriding type MyType in trait A with bounds <: AInner;
type MyType is a volatile type; cannot override a type with non-volatile upper bound
これは仕様と一致しています。 BInner with A#MyType
は揮発性です。その前にMyType
は不揮発性がAny
であった。
スカラ型システムの型は、固有の意味を持たなければならないということです。抽象型は、宣言がサブクラスに継承される型と考えることができます。したがって抽象型の値を宣言する際には抽象型のままであれば問題ありません。一方、BInner with A#MyType
のようなタイプの場合、このタイプにはいくつかの意味があります。これはvolatileと呼ばれ、MyType
抽象タイプをインスタンス化するサブクラスと同じ型を持つことができるので、この型の非null値を持つことは意味がありません。事態を単純化するために、揮発性タイプは、サブタイプではないタイプ(Any
(かつ揮発性タイプはサブタイプAny
)と考えることができます)。したがって、コンパイラには矛盾があります。
あなたはこのような内部の特徴には、このおかげで達成することができます
What I'm trying to achieve here(in trait B) is to further restrict the type MyType declared > in Abstract, so any value of type MyType must extend all the MyTypes in the mixin tree.
としてあなたが述べ、あなたの目標に戻って来ます。
trait Abstract {
type MyType
}
trait B extends Abstract {
trait MyType {
def bMethod : Int
}
}
trait A extends B {
trait MyType extends super.MyType {
}
}
これはあなたが探しているものです。
非揮発性タイプで抽象メソッドメンバが禁止されているのはなぜですか? – Blaisorblade