https://medium.com/@scelestino/inheritance-vs-self-types-eff8cf41d787
위 포스트 정리
trait Animal {
def stop(): Unit = println("it stops")
}
class Dog extends Animal {
def bark: String = "Woof!"
}
val goodboy: Dog = new Dog
trait Security {
this: Animal => // 셀프 타입 사용
def lookout: Unit = { stop(); println("looking out!") }
}
trait Human {
def stop(): Unit = println("human stops")
}
class Man extends Human {
def shout: String = "Wow"
}
val guardDog = new Dog with Security // 성공! Animal 인 Dog 에 mix-in 했으므로
val normalMan = new Man with Security // 실패! Man 은 Animal 이 아니므로
하지만, Security 를 extends Animal 한다면
trait Security extends Animal {
def lookout: Unit = { stop(); println("looking out!") }
}
val normalMan = new Man with Security // 컴파일은 성공!
normalMan.lookout // 실패! Animal 과 Human 모두 stop 이 있으므로 어떤 걸 호출할지 모른다.
// 컴파일 되지 않아야 정상!
trait Security {
this: { def stop():Unit } => // stop 이 존재하기만 하면 OK, override 하도록?
def lookout: Unit = { stop(); println("looking out!") }
}
val securityGuard = new Human with Security
securityGuard.lookout
// it stops and crosses their arms
// looking out!
val guardDog = new Dog with Security
guardDog.lookout
// it stops
// looking out!
Human , Dog 모두에게 Security 를 적용 가능해졌다.
trait A extends B
trait B extends A
// illegal cyclic reference involving trait A!!
이건 당연히 에러
하지만 self type 을 이용하면
trait A {
this: B =>
}
trait B {
this: A =>
}
// 가능!