멤버 재정의
Coddy Kotlin 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 18번째.
하위 클래스는 상속된 메서드를 자체 버전으로 대체할 수 있습니다. 상위 클래스는 메서드를 open으로 표시하고, 하위 클래스는 override를 사용하여 이를 다시 선언합니다:
open class Animal(val name: String) {
open fun sound() = "..."
}
class Dog(name: String) : Animal(name) {
override fun sound() = "Woof"
}
class Cat(name: String) : Animal(name) {
override fun sound() = "Meow"
}main 내부:
println(Dog("Rex").sound())
println(Cat("Tom").sound())
println(Animal("Generic").sound())출력:
Woof
Meow
...실행되는 버전은 변수의 타입이 슈퍼클래스인 경우에도 객체의 실제 클래스에 의해 선택됩니다. 슈퍼클래스 내부에서 open 메서드를 호출하는 코드도 서브클래스의 버전을 가져옵니다:
open class Animal(val name: String) {
open fun sound() = "..."
fun speak() = "$name says ${sound()}"
}
class Dog(name: String) : Animal(name) {
override fun sound() = "Woof"
}main 내부에서:
val pets: List<Animal> = listOf(Dog("Rex"), Animal("Generic"))
for (p in pets) println(p.speak())출력:
Rex says Woof
Generic says ...속성도 같은 방식으로 재정의할 수 있습니다. 상위 클래스에서는 open val, 하위 클래스에서는 override val을 사용하며, 일반 속성, 생성자 속성 또는 계산된 getter로 작성할 수 있습니다.
open class Shape {
open val name = "shape"
open val corners = 0
}
class Triangle : Shape() {
override val name = "triangle"
override val corners = 3
}
class Polygon(override val corners: Int) : Shape() {
override val name: String
get() = "$corners-gon"
}main 내부에서:
for (s in listOf(Shape(), Triangle(), Polygon(6))) println("${s.name}: ${s.corners}")출력:
shape: 0
triangle: 3
6-gon: 6override로 표시된 멤버는 다시 열려 있으므로 서브클래스의 서브클래스가 이를 한 번 더 오버라이드할 수 있습니다. final override는 이를 막습니다. open이 없는 멤버는 어떤 경우에도 오버라이드할 수 없으며, 서브클래스는 동일한 시그니처를 가진 멤버를 선언할 수 없습니다:
open class Animal {
open fun sound() = "..."
fun sleep() = "zzz"
}
open class Dog : Animal() {
final override fun sound() = "Woof"
}
class Puppy : Dog() {
// override fun sound() = "Yip" // 오류: 'Dog'의 'sound'는 final입니다
// fun sleep() = "nap" // 오류: 'sleep'이 슈퍼클래스의 멤버를 숨깁니다
}챌린지
쉬움Animal에는 legs()(4), sound()(...) 및 describe()가 있으며, legs()와 sound()를 바탕으로 Rex has 4 legs and says Woof를 반환합니다. legs()와 sound()를 재정의할 수 있도록 만들고, 다음 두 메서드만 재정의하여 하위 클래스를 완성하세요. Dog는 Woof라고 말하고, Bird는 다리가 2개이며 Tweet이라고 말하고, Snake는 다리가 0개이며 Hiss라고 말합니다. describe()는 Animal에 있는 그대로 유지됩니다.
제공된 코드는 dog,Rex, bird,Pip, snake,Kaa 또는 다른 종류의 입력(일반 Animal)을 읽고, 동물들을 하나의 List<Animal>에 저장한 다음 각각에 대해 describe()를 출력합니다.
코드는 Animal.kt, Dog.kt, Bird.kt 및 Snake.kt에 작성하세요. Main.kt에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.
직접 해보기
fun main() {
// 제공된 입력/출력 코드: 그대로 유지하세요
val input = generateSequence(::readLine).toList()
val animals = mutableListOf<Animal>()
for (line in input) {
val (kind, name) = line.split(",")
animals.add(when (kind) {
"dog" -> Dog(name)
"bird" -> Bird(name)
"snake" -> Snake(name)
else -> Animal(name)
})
}
for (a in animals) println(a.describe())
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: Kotlin 플레이그라운드