타입 파라미터의 섀도잉을 피하라
//프로퍼티, 파라미터가 같은 경우
class Forest(
val name: String
) {
fun addTree(name: String) { //같은 이름(name)을 가지고 있다
}
}
또한 클래스 타입 파라미터와 함수 타입 파라미터가 같은 경우도 존재한다.
//(1) Bad
interface Tree
class Birth: Tree
class Spruce: Tree
class Forest<T: Tree> {
fun <T: Tree> addTree(tree: T) {
}
}
val forest = Forest<Birch>()
forest.addTree(Birch())
forest.addTree(Spruce())
//(2) Good
interface Tree
class Birch: Tree
class Spruce: Tree
class Forest<T: Tree> {
fun addTree(tree: T) {
}
}
fun main() {
val forest = Forest<Birch>()
forest.addTree(Birch())
forest.addTree(Spruce())// Error!! 클래스에서 타입을 지정했으므로 Type mismatch
}
(1)처럼 작성한다면 타입 파라미터가 독립적으로 동작한다. 따라서 독립적으로 동작하는 것을 의도하지 않았다면 (2)와 같이 섀도잉을 없애도록 하는 것이 좋다.
독립적인 타입 파라미터를 의도했다면 이름을 다르게 하는 것이 좋다. 또한 클래스의 타입을 이용해 함수에 타입 제한을 걸 수도 있다.
class Forest<T: Tree> {
fun <ST: T> addTree(tree: ST) {
}
}