기본적으로 코틀린에서 클래스 하나가 여러개의 클래스를 상속받는 것은 불가능하다.
그렇지만 인터페이스를 사용하면 하나의 클래스가 여러개의 인터페이스를 상속받을 수 있다.
그럼 예제를 통해 인터페이스의 활용을 알아보자
interface Vehicle {
// interface는 interface만을 상속할 수 있다.
// abstract가 붙은 것으로 간주
// interface는 상태를 가질 수 없다. -> 프로퍼티가 메모리를 가질 수 없다.
// 프로퍼티가 메모리를 가질 수 없도록 구현은 가능하나, 메모리를 갖는다면 오류가 발생한다.
val currentSpeed: Double
val isMoving get() = currentSpeed != 0.0
fun move()
fun stop()
fun report() {
println(if (isMoving) "Moving at $currentSpeed" else "Still")
}
}
class Car: Vehicle {
override var currentSpeed: Double = 0.0
private set // set을 private하게 설정하기 위함.
override fun move() {
println("Start riding")
currentSpeed = 50.0
}
override fun stop() {
println("Stop riding")
currentSpeed = 0.0
}
}
fun main() {
val v: Vehicle = Car()
v.move()
v.report()
v.stop()
v.report()
}
인터페이스의 모든 프로퍼티와 함수는 abstract가 붙은 것으로 간주하며, 추상 클래스와 마찬가지로 초기화 할 수 없다.
그러나 초기화가 만약 메모리를 잡지 않는다면 초기화가 가능하다.
interface Car {
fun moving() {
println("I'm riding.")
}
}
interface Airplane {
fun moving() {
println("I'm flying.")
}
}
class Transformers(var isCar: Boolean): Car, Airplane {
override fun moving() {
if (isCar) super<Car>.moving()
else super<Airplane>.moving()
}
}
fun main() {
val starscream = Transformers(false)
val bumblebee = Transformers(true)
starscream.moving() // I'm flying.
bumblebee.moving() // I'm riding.
}
다중 상속을 통한 동일한 이름의 메서드의 충돌이 발생하더라도 super<Interface>로 인터페이스를 명시하여 해결할 수 있다.