코틀린 인터페이스는 자바와 비슷하다. 코틀린 인터페이스는 추상 메소드뿐 아니라, 구현이 있는 메소드도 정의가 가능하다.
interface Clickable {
fun click()
fun longClick() = "long click"
}
class Button : Clickable {
override fun click() = println("click")
// 선택
override fun longClick(): String {
}
}
디폴트 메소드는 그냥 사용해도 되고, 재정의해서 사용해도 상관 없다.
interface Clickable {
fun click()
fun longClick() = println("click long click")
}
interface Focusable {
fun click()
fun longClick() = println("focus long click")
}
class Button : Clickable, Focusable {
override fun click() = println("click")
override fun longClick() {
super<Clickable>.longClick()
super<Focusable>.longClick()
}
}
val button = Button().longClick()
출력결과 :
"click long click"
"focus long click"
디폴트 구현이 되어있고 이름이 같은 메소드는 하위 클래스에서 직접 구현하게 강제된다. → 인터페이스에서 이미 구현이 되어있으므로, 구현이 모호하지 않다.
디폴트 구현이 되어있지 않고, 메소드 이름이 같은 경우는 인터페이스의 메소드 충돌이 일어나 메소드의 이름을 다르게 해줘야 한다. → 컴파일러가 구현을 해석하는 방법을 찾지 못한다.
final
로 만들자.open class RichButton : Clickable { // open 키워드를 사용해서 다른 클래스가 상속이 가능.
fun disable() // final 함수. 하위 클래스가 이 메소드를 오버라이드 불가능
open fun animate() // 하위 클래스에서 이 메소드를 오버라이드 가능
override fun click() {
// 오버라이드한 메소드는 기본적으로 open이다.
// 해당 메소드를 재정의 못하게 금지시키려면 override 앞에 final 키워드를 명시하면 된다.
...
}
}
internal
이라는 새로운 가시성 변경자를 도입했다. 이는 모듈 내부에서만 볼수 있다는 뜻이다.<aside> 💡
모듈이란? 하나 이상의 패키지와 파일을 묶어서 관리하는 논리적인 단위
</aside>
모듈 내부 가시성은 모듈의 구현에 대해 진정한 캡슐화를 제공한다는 장점이 있다.
변경자 | 클래스 멤버 | 최상위 선언 |
---|---|---|
public(기본 가시성) | 모든 곳에서 볼 수 있다. | 모든 곳에서 볼 수 있다. |
internal | 같은 모듈 안에서만 볼 수 있다. | 같은 모듈 안에서만 볼 수 있다. |
protected | 하위 클래스 안에서만 볼 수 있다. | 최상위 선언에 적용할 수 없다. |
private | 같은 클래스 안에서만 볼 수 있다. | 같은 파일 안에서만 볼 수 있다. |