내 코드도 클로드한테 위임해
코틀린에서 위임(delegate) 패턴과 상속(Inheritance)은 둘 다 객체의 재사용 및 확장을 위한 방법이지만, 사용하는 방식과 적용 목적에서 차이가 있다.
부모 클래스의 기능을 자식 클래스가 상속받아 재사용할 수 있게 한다.
단일 상속만을 지원하므로, 하나의 클래스만 상속할 수 있다.
상속된 클래스는 부모 클래스의 메서드를 오버라이드할 수 있으며, 부모 클래스의 기능을 확장하거나 수정하여 사용할 수 있다.
상속 관계는 IS-A 관계라고 하며, 자식 클래스는 부모 클래스의 일종으로 간주된다.
Is-a는 추상화(형식이나 클래스와 같은)들 사이의 포함 관계를 의미하며, 한 클래스 A가 다른 클래스 B의 서브클래스(파생클래스)임을 이야기한다. 다른 말로, 타입 A는 타입 B의 명세(specification)를 암시한다는 점에서 타입 B의 서브타입이라고도 할 수 있다.
Is-a 관계는 타입 또는 클래스 간의 Has-a 관계와는 대조된다. Has-a 및 Is-a 관계들 간의 혼동은 실세계 관계 모델에 대한 설계에 있어 자주 발견되는 에러이다. Is-a 관계는 또한 객체 또는 타입 간의 instance-of 관계와도 대조된다.
특징
- 부모 클래스의 메서드와 속성을 상속
- 단일 상속만 가능
- 부모 클래스와 강한 결합
- 객체 간의 관계가 본질적으로 IS-A 관계일 때, 즉 한 객체가 다른 객체의 일종일 때 사용
사용 예시
open class Developer {
open fun work() = "develop..."
}
class AndroidDeveloper : Developer() {
override fun work() = "develop android app..."
}
class AppDeveloper: AndroidDeveloper()
val appDeveloper = AppDeveloper()
appDeveloper.work() // "develop android app..."
위와 같이 사용한다면 유연한 설계가 불가능하고 AppDeveloper는 AndroidDeveloper class에 강하게 결합된다.
특정 객체에 작업을 위임하여 해당 객체의 기능을 활용할 수 있다.
HAS-A 관계로, 객체는 위임된 클래스의 기능을 가지면서 해당 클래스와 협력하여 작업을 수행한다.
구성(composition)을 이용해 객체를 구성하고, 인터페이스나 다른 클래스의 구현을 위임함으로써 다중 상속이 필요한 경우 유용하게 사용할 수 있다.
코틀린에서는 by 키워드를 사용해 인터페이스에 대한 위임을 간단히 구현할 수 있다.
특징
- 위임 객체의 메서드를 사용
- 여러 위임 객체를 통해 다중 기능 가능
- 유연하며 교체 가능성 높음
- 유연한 설계가 필요하거나, 다중 상속이 필요한 상황에서 구성(composition)을 통해 기능을 추가하고자 할 때 유용
사용 예시
interface Developer {
fun work(): String
}
class AndroidDeveloper : Developer {
override fun work() = "develop android app"
}
class AppDeveloper(private val developer: Developer) : Developer by developer
val appDeveloper = AppDeveloper(AndroidDeveloper())
appDeveloper.work() // "develop android app"
위와 같이 사용한다면 AppDeveloper는 AndroidDeveloper와 강하게 결합되지 않아 다음과 같이 유연한 사용이 가능하다.
class IOSDeveloper: Developer {
override fun work(): String = "develop ios app"
}
val appDeveloper = AppDeveloper(IOSDeveloper())
appDeveloper.work() // "develop ios app"
위의 코드를 보면 AppDeveloper 클래스는 Developer 인터페이스를 구현하지만 AndroidDeveloper나 IOSDeveloper 클래스를 상속하지는 않는다.
상속의 경우 is 관계가 확실하면 사용하는 것이 좋다.
구성(composition)의 경우, 하나의 객체가 다른 객체에 부분적으로 포함 하는 경우 사용할 수 있다.