循環依存関係から始めましょう。
trait A {
selfA: B =>
def fa: Int }
trait B {
selfB: A =>
def fb: String }
ただし、このソリューションのモジュール性は、セルフタイプを次のようにオーバーライドできるため、最初に表示されるほど優れていません。
trait A1 extends A {
selfA1: B =>
override def fb = "B's String" }
trait B1 extends B {
selfB1: A =>
override def fa = "A's String" }
val myObj = new A1 with B1
ただし、自己型のメンバーをオーバーライドすると、元のメンバーへのアクセスが失われますが、継承を使用してスーパーから引き続きアクセスできます。したがって、継承を使用することで実際に得られるものは次のとおりです。
trait AB {
def fa: String
def fb: String }
trait A1 extends AB
{ override def fa = "A's String" }
trait B1 extends AB
{ override def fb = "B's String" }
val myObj = new A1 with B1
今、私はケーキのパターンのすべての微妙な点を理解していると主張することはできませんが、モジュール性を強制する主な方法は、継承や自己型ではなく構成を介することです。
継承バージョンは短いですが、自己型よりも継承を好む主な理由は、自己型を使用して初期化順序を正しく取得するのがはるかに難しいことです。ただし、継承では実行できないセルフタイプで実行できるいくつかの処理があります。自己型は型を使用できますが、継承では次のように特性またはクラスが必要です。
trait Outer
{ type T1 }
trait S1
{ selfS1: Outer#T1 => } //Not possible with inheritance.
あなたも行うことができます:
trait TypeBuster
{ this: Int with String => }
それをインスタンス化することはできませんが。型から継承できない絶対的な理由はわかりませんが、型コンストラクタの特性/クラスがあるため、パスコンストラクタのクラスと特性があると便利だと思います。残念ながら
trait InnerA extends Outer#Inner //Doesn't compile
これがあります:
trait Outer
{ trait Inner }
trait OuterA extends Outer
{ trait InnerA extends Inner }
trait OuterB extends Outer
{ trait InnerB extends Inner }
trait OuterFinal extends OuterA with OuterB
{ val myV = new InnerA with InnerB }
またはこれ:
trait Outer
{ trait Inner }
trait InnerA
{this: Outer#Inner =>}
trait InnerB
{this: Outer#Inner =>}
trait OuterFinal extends Outer
{ val myVal = new InnerA with InnerB with Inner }
さらに共感すべき点は、特性がクラスを拡張できることです。これを指摘してくれたDavid Maclverに感謝します。これが私のコードの例です。
class ScnBase extends Frame
abstract class ScnVista[GT <: GeomBase[_ <: TypesD]](geomRI: GT) extends ScnBase with DescripHolder[GT] )
{ val geomR = geomRI }
trait EditScn[GT <: GeomBase[_ <: ScenTypes]] extends ScnVista[GT]
trait ScnVistaCyl[GT <: GeomBase[_ <: ScenTypes]] extends ScnVista[GT]
ScnBase
Swing Frameクラスから継承するため、それをselfタイプとして使用し、最後に(インスタンス化時に)混合できます。ただし、val geomR
継承トレイトで使用する前に初期化する必要があります。したがって、の事前初期化を強制するクラスが必要ですgeomR
。ScnVista
その後、クラスは、それ自体から継承できる複数の直交特性によって継承できます。複数の型パラメーター(ジェネリック)を使用すると、モジュール化の代替形式が提供されます。