class Car(
val type: CarType, // enum 태그 (SPORTS, FAMILY)
val name: String,
val maxSpeed: Int?, // Sports car만 필요
val turboEngine: Boolean?, // Sports car만 필요
val seatingCapacity: Int?, // Family car만 필요
val trunkSize: Int? // Family car만 필요
) {
enum class CarType {
SPORTS,
FAMILY
}
fun describe() = when(type) {
CarType.SPORTS -> "${name}은 최고속도 ${maxSpeed}km/h의 스포츠카입니다."
CarType.FAMILY -> "${name}은 ${seatingCapacity}인승 패밀리카입니다."
}
}
// 사용
val porsche = Car(
type = Car.CarType.SPORTS,
name = "911",
maxSpeed = 300,
turboEngine = true,
seatingCapacity = null, // 불필요
trunkSize = null // 불필요
)
sealed class Car // sealed로 선언
// 같은 파일 안에서만 Car를 상속할 수 있음
class SportsCar(val maxSpeed: Int) : Car() // OK
class FamilyCar(val seatingCapacity: Int) : Car() // OK
// 다른 파일(OtherCars.kt)에서는 상속 불가능
class ElectricCar(val batteryCapacity: Int) : Car() // 컴파일 에러!
하위 클래스를 컴파일 타임에 알 수 있음
sealed class Car
class SportsCar(val maxSpeed: Int) : Car()
class FamilyCar(val seatingCapacity: Int) : Car()
fun processCar(car: Car) = when(car) {
is SportsCar -> "최고속도: ${car.maxSpeed}km/h"
is FamilyCar -> "좌석수: ${car.seatingCapacity}인승"
// 다른 타입이 없다는 것을 컴파일러가 알고 있어서
// else나 다른 케이스가 필요 없음
}
open class Car // 일반 open 클래스
class SportsCar : Car()
class FamilyCar : Car()
fun processCar(car: Car) = when(car) {
is SportsCar -> "스포츠카"
is FamilyCar -> "패밀리카"
else -> "다른 차량" // else 필수! (다른 하위 클래스가 추가될 수 있음)
}