Menu
Coddy logo textTech

Open 클래스와 하위 클래스

Coddy Kotlin 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 17번째.

상속을 사용하면 한 클래스가 다른 클래스를 기반으로 확장될 수 있습니다. 서브클래스는 슈퍼클래스의 모든 프로퍼티와 메서드를 얻으며, 자체 프로퍼티와 메서드를 추가할 수도 있습니다. Kotlin 클래스는 기본적으로 닫혀 있으므로 다른 클래스가 이를 확장하려면 먼저 클래스에 open을 표시해야 합니다:

open class Animal(val name: String) {
    fun describe() = "$name is an animal"
}

class Dog(name: String) : Animal(name) {
    fun fetch() = "$name fetches the ball"
}

main 내부:

val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())

출력:

Rex is an animal
Rex fetches the ball

class Dog(name: String) : Animal(name)은 Dog이 Animal을 확장하고 name을 슈퍼클래스 생성자에 전달한다는 의미입니다. Animal에 이미 속성이 존재하므로 매개변수에는 val이 없습니다. open이 아닌 클래스는 확장할 수 없습니다:

class Plant(val name: String)
// class Tree(name: String) : Plant(name)   // error: 이 타입은 final이므로 확장할 수 없습니다

open class Vehicle(val wheels: Int)
class Bike : Vehicle(2)                     // 고정된 값을 전달합니다
class Truck(val load: Int) : Vehicle(6)     // 자체 속성을 추가합니다

Dog는 Animal이므로 서브클래스 인스턴스는 슈퍼클래스 타입이 예상되는 모든 곳에서 사용할 수 있습니다. 하나의 List<Animal>에는 개, 고양이, 일반 동물을 담을 수 있으며, 모든 요소는 Animal의 멤버를 가집니다:

open class Animal(val name: String) {
    fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)

main 내부:

val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())

출력:

Rex is an animal
Tom is an animal
Generic is an animal

상속은 is-a 관계를 모델링합니다. 개는 동물이고, 저축 계좌는 계좌입니다. 한 클래스가 다른 클래스를 단지 사용하기만 한다면(자동차가 엔진을 가지고 있는 경우) 대신 해당 타입의 프로퍼티를 제공하세요. Kotlin에서는 폐쇄적인 클래스가 기본값이므로, 확장을 의도한 클래스는 open으로 이를 명시하고, 그 외의 모든 클래스는 서브클래스로부터 동작을 안전하게 보호합니다.

open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner)   // is-a: 상속

class Engine(val horsepower: Int)
class Car(val engine: Engine)                          // has-a: 속성
challenge icon

챌린지

쉬움

Manager는 Employee가 이미 가진 기능을 반복합니다. Employee를 open으로 만들고 Manager를 그 서브클래스로 바꾸세요. Manager(name: String, salary: Int)는 두 값을 모두 Employee에 전달하고, 새로운 부분인 보고자 이름의 private 목록과 addReport(name) 및 teamSize()만 추가합니다. Employee에서 raise(percent)는 해당 비율만큼 급여를 올리며, 결과는 내림 처리하고, describe()는 Ada earns 5500을 반환합니다.

제공된 코드는 첫 번째 줄(name,salary)에서 관리자를 만들고, 다음에 나오는 각 이름을 보고자로 추가하며, 10% 인상을 적용한 뒤 Ada earns 5500 and leads 2를 출력합니다. 그런 다음 관리자가 Employee인지 확인합니다.

여러분의 코드는 Employee.kt와 Manager.kt에 작성합니다. Main.kt에는 제공된 입력/출력 코드가 들어 있으며 수정할 수 없습니다.

직접 해보기

fun main() {
    // 제공된 입출력 코드: 있는 그대로 유지하세요
    val input = generateSequence(::readLine).toList()
    val (name, salary) = input[0].split(",")
    val boss = Manager(name, salary.toInt())
    for (report in input.drop(1)) boss.addReport(report)
    boss.raise(10)
    println("${boss.describe()} and leads ${boss.teamSize()}")
    println("a manager is an employee: ${(boss as Any) is Employee}")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: Kotlin 플레이그라운드