지난번 포스팅에 이어~ 이번에는 코틀린 인터페이스에 대해 정리해보려 한다.
인터페이스
코틀린의 인터페이스는 추상 메소드 뿐 아니라 구현된 메소드(Java 8 의 default
메소드와 비슷)도 정의할 수 있다. 상태를 가질 수 없다는 점에서 abstract class
와는 다르다.
인터페이스 정의
인터페이스 정의는 interface
키워드를 사용하며, 여타 언어와 비슷한 모양이다.
interface Notifiable {
fun notify()
}
그리고, 아래와 같이 이 인터페이스를 구현할 수 있다.
class EmailNotifier: Notifiable {
override fun notify() = println("notify 메소드 구현")
}
자바에서는 implements
키워드를 사용하여 인터페이스를 구현하지만 코틀린은 :
(콜론) 붙이고 인터페이스 이름을 적어 해당 인터페이스를 구현하는 것을 명시한다.
그리고, 상위 인터페이스의 메소드 또는 프로퍼티를 오버라이딩하기 위해 override
키워드를 꼭 붙여야 하는데, 실수로 상위 클래스의 메소드를 오버라이딩하는 경우를 막기 위해서이다.
위에서 잠깐 언급했듯이, 자바8부터 인터페이스에 메소드의 기본 구현을 제공할 수 있는데, 코틀린도 마찬가지다. 다만, 자바에선 default
키워드를 사용했다면 코틀린에서는 그럴 필요가 없다.
interface Notifiable {
fun notify() = println("default 함수 구현")
}
인터페이스 상속
코틀린도 자바와 마찬가지로, 하나의 인터페이스가 또 다른 인터페이스를 상속할 수 있다.
interface ExceptionHandler {
fun handleException(ex: Exception)
}
interface Notifier: ExceptionHandler {
fun send() = println("default 함수 구현")
}
자식 인터페이스는 부모 인터페이스의 함수를 오버라이딩하여 구현할 수 있다. 그리고, (당연하겠지만..) 이 인터페이스를 구현하는 클래스는 구현이 되어 있지 않은 함수에 대해서만 구현해도 된다.
interface Notifier: ExceptionHandler {
fun send() = println("default 함수 구현")
override fun handleException(ex: Exception) =
println("예외 처리 기본 구현")
}
class MailNotifier: Notifier {
override fun send() = println("메일 알림 실행")
}
오버라이딩 충돌 해결
두 개 이상의 인터페이스를 구현하려고 할 때, 가끔 이 인터페이스들 내 같은 이름의 메소드를 가지고 있는 경우가 있다.
interface Notifier {
fun send() = println("default 함수 구현")
}
interface MessageSender {
fun send()
}
class MailNotifier: Notifier, MessageSender {
// send() 를 오버라이딩 하지 않으면 오류!!
}
만약, 위의 경우와 같이 Notifier
인터페이스의 send
메소드는 default 구현이 되어 있는 상태이고, MessageSender
인터페이스의 send
는 default 구현이 없는 상태라고 하면, 이들 인터페이스를 구현하는 클래스에서는 당연하게도, send
메소드를 무조건 구현해줘야 한다.
MessageSender
인터페이스의 send
에 대한 구현 로직이 없으니 오류가 나는게 당연하다!
그럼, 아래와 같이, MessageSender
도 send
메소드가 default 메소드로 정의되어 있다면 어떻게 될까?
interface Notifier {
fun send() = println("Notifier 의 send 함수 구현")
}
interface MessageSender {
fun send() = println("MessageSender 의 send 함수 구현")
}
class MailNotifier: Notifier, MessageSender {
// send() 를 오버라이딩 하지 않으면 오류!!
}
이런 경우에도 오류가 발생하는데, 이때엔 코틀린 컴파일러가 어떤 인터페이스의 send 메소드를 사용할지 구분할 수 없기 때문이다.
컴파일 오류를 없애기 위해선, 아래 코드처럼, 어떤 인터페이스의 구현을 사용할지 명시적으로 선택할 수도 있고, 아예 새로운 동작을 구현해도 된다.
class MailNotifier: Notifier, MessageSender {
override fun send() {
super<Notifier>.send()
super<MessageSender>.send()
}
// 또는 아예 새롭게 구현
// override fun send() = println("MailNotifier 의 send 함수 구현")
}
코틀린의 인터페이스에 대해 정리해보았다. 자바에 대해 이미 익숙한 프로그래머라면 지겨울 수 있는 내용이겠지만, 기초는 튼튼할수록 좋은거니깐.. 조바심 가지지 말고, 기초부터 확실히 내 것으로 만들고 가자!!