클래스를 상속받아서 구현할 때, 슈퍼 클래스에 구현되어있는 매서드를 서브 클래스가 재정의하여 구현하는 기능이다.
클래스를 상속할때와 마찬가지로 매서드에 'open'키워드를 붙여야한다.
오버라이딩하는 매서드에는 'override'키워드를 붙여 재구현하면 된다.
open class Animal() {
open fun eat() {
println("eat food")
}
}
class Tiger : Animal() {
override fun eat() {
println("eat meat")
}
}
fun main() {
var t = Tiger()
t.eat() // "eat meat"이 출력된다
}
슈퍼 클래스에서는 구체적인 구현이 없지만, 서브 클래스에서는 구현해야하는 매서드들을 명시할때 사용하는 개념이 추상화이다.
추상화 개념이 사용된 클래스를 추상 클래스라고 한다
// 추상 클래스
abstract class Animal() {
abstract fun eat() // 추상 매서드
fun sniff() {
println("킁킁")
}
}
class Rabbit : Animal() {
// 추상 클래스를 상속 받으면 반드시 추상 매서드를 구현해야한다.
override fun eat() {
println("eat carrot")
}
}
fun main() {
var r = Rabbit()
r.sniff()
r.eat()
}
원래 인터페이스란 추상함수로만 이루어져있는 좀 더 순수한(?) 추상화 기능이다.
하지만 코틀린에서는 그 개념이 약간 다르다.
인터페이스에서 구현부를 가질 수 있으며, 구현부 유무에 따라 아래와 같은 특징을 가진다.
즉, 별도의 키워드가 없어도 정의된 매서드들을 서브 클래스에서 구현 및 재정의가 가능하다.
인터페이스는 클래스의 상속과 다르게 여러개를 상속 받을 수 있다.
그리고 Kotlin에서 인터페이스는 생성자를 가질 수 없다.
interface Runner {
// abstract로 간주
fun run()
}
interface Eater {
// open로 간주
fun eat() {
println("eat foot")
}
}
class Dog : Runner, Eater {
override fun run() {
println("run!!")
}
override fun eat() {
println("Dog eat foot")
}
}
fun main() {
var d = Dog()
d.run()
d.eat()
}