원래는 상속받은 서브클래스에서는 함수를 재구현 할 수 없다.
함수 앞에 open을 붙이면 override를 통해 재구현이 허용된다.
서브클래스에서 같은 이름과 형태로 된 함수의 내용을 다시 구현할 수 있다.
이미 구현이 끝난 함수의 기능을 서브클래스에서 변경해야할 때,
추상화는 형식만 선언하고 실제 구현은 서브클래스에 일임할 때 사용하는 기능
fun main() {
var t = Tiger()
t.eat()
}
open class Animal {
open fun eat() {
println("음식을 먹습니다")
}
}
class Tiger : Animal() {
override fun eat() {
println("고기를 먹습니다")
}
}
고기를 먹습니다
수퍼클래스에서는 함수의 구체적인 구현은 없고 단지 Animal의 모든 서브클래스는 eat() 함수가 반드시 있어야한다는 점만 명시하여 각 서브클래스가 비어있는 함수의 내용을 필요에 따라 구현하도록 하려면 '추상화' 개념을 사용한다.
fun main() {
var r = Rabbit() // Rabbit의 인스턴스 만들기
r.eat()
r.sniff()
}
abstract class Animal {
abstract fun eat()
fun sniff() {
println("킁킁")
}
}
class Rabbit : Animal() {
// 서브클래스에서 상속을 받아 abstract가 된 함수들을 구현
override fun eat() {
println("당근을 먹습니다")
}
}
당근을 먹습니다
킁킁
추상화를 하는 또 다른 기능
속성 / 추상함수 / 일반함수 전부 포함 !
추상함수는 생성자를 가질 수 있는 반면 인터페이스는 생성자를 가질 수는 없다.
서로 다른 기능들을 여러개 물려주어야할 때 유용한 기능
fun main() {
var d = Dog() // Rabbit의 인스턴스 만들기
d.run()
d.eat()
}
interface Runner {
fun run()
}
interface Eater {
fun eat() {
println("음식을 먹습니다")
}
}
class Dog : Runner, Eater {
// 구현부가 없는 run 함수에 출력 구현
override fun run() {
println("음식을 먹습니다")
}
// 구현부가 있는 eat 함수에 출력 재구현
override fun eat() {
println("허겁지겁 먹습니다")
}
}
음식을 먹습니다
허겁지겁 먹습니다