섀도잉은 지역 변수나 파라미터가 동일한 이름을 가진 외부 스코프의 변수를 가리는 현상이다.
class Forest(val name: String) {
fun addTree(name: String) {
println(name) // 메서드의 파라미터 name이 클래스의 프로퍼티 name을 가림
}
}
addTree
메서드의 파라미터 name
은 클래스의 프로퍼티 name
을 가리게 된다. 이는 지역 스코프가 더 높은 우선순위를 가지기 때문이다.this.name
을 사용해야 한다.먼저 간단한 제네릭 Forest 클래스를 살펴보자.
class Forest<T> {
fun addTree(tree: T) {
// T 타입의 나무를 추가
}
}
타입 안정성을 높이기 위해 타입 파라미터에 제한을 추가할 수 있다.
class Forest<T: Tree> {
fun <T : Tree> addTree(tree: T) {
// But, 이때 T는 클래스 프로퍼티 T와는 완전 독립적인 타입
}
}
<T : Tree>
를 선언했기 때문에, 클래스의 타입 파라미터 T와는 완전히 독립적인 새로운 타입 파라미터를 정의한 것이다.interface Tree
class Birch: Tree
class Spruce: Tree
val forest = Forest<Birch>()
forest.addTree(Birch()) // 가능
forest.addTree(Spruce()) // 이것도 가능