주기적 의존성부터 시작하겠습니다.
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
자체 유형의 멤버를 대체하는 경우에도 상속을 사용하여 super를 통해 액세스 할 수있는 원래 멤버에 대한 액세스 권한이 손실됩니다. 따라서 상속을 통해 실제로 얻는 것은 다음과 같습니다.
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 프레임 클래스 에서 상속 되므로 자체 유형으로 사용 된 다음 마지막에 인스턴스화 할 수 있습니다. 그러나 val geomR
특성을 상속하여 사용하기 전에 초기화해야합니다. 따라서 사전 초기화를 시행하는 클래스가 필요합니다 geomR
. ScnVista
그런 다음 클래스 는 자체에서 상속받을 수있는 여러 직교 특성으로 상속 될 수 있습니다. 여러 유형의 매개 변수 (일반)를 사용하면 다른 형태의 모듈성이 제공됩니다.