코틀린 인터페이스

코틀린 인터페이스는 자바와 비슷하다. 코틀린 인터페이스는 추상 메소드뿐 아니라, 구현이 있는 메소드도 정의가 가능하다.

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"

디폴트 구현이 되어있고 이름이 같은 메소드는 하위 클래스에서 직접 구현하게 강제된다. → 인터페이스에서 이미 구현이 되어있으므로, 구현이 모호하지 않다.

디폴트 구현이 되어있지 않고, 메소드 이름이 같은 경우는 인터페이스의 메소드 충돌이 일어나 메소드의 이름을 다르게 해줘야 한다. → 컴파일러가 구현을 해석하는 방법을 찾지 못한다.

취약한 기반 클래스

open class RichButton : Clickable { // open 키워드를 사용해서 다른 클래스가 상속이 가능.
		fun disable() // final 함수. 하위 클래스가 이 메소드를 오버라이드 불가능
		open fun animate() // 하위 클래스에서 이 메소드를 오버라이드 가능
		override fun click() { 
		// 오버라이드한 메소드는 기본적으로 open이다.
		// 해당 메소드를 재정의 못하게 금지시키려면 override 앞에 final 키워드를 명시하면 된다.
				...
		}
}

가시성 변경자

<aside> 💡

모듈이란? 하나 이상의 패키지와 파일을 묶어서 관리하는 논리적인 단위

</aside>

모듈 내부 가시성은 모듈의 구현에 대해 진정한 캡슐화를 제공한다는 장점이 있다.

변경자 클래스 멤버 최상위 선언
public(기본 가시성) 모든 곳에서 볼 수 있다. 모든 곳에서 볼 수 있다.
internal 같은 모듈 안에서만 볼 수 있다. 같은 모듈 안에서만 볼 수 있다.
protected 하위 클래스 안에서만 볼 수 있다. 최상위 선언에 적용할 수 없다.
private 같은 클래스 안에서만 볼 수 있다. 같은 파일 안에서만 볼 수 있다.