Sealed Classes
이름, 전화번호, 이메일 데이터를 표현하는 interface와 클래스를 정의하고 해당 데이터를 출력하는 메소드를 정의한다고 하면..
interface Data
class NameData(val value: String) : Data
class PhoneData(val value: String, val type: String) : Data
class EmailData(val value: String, val type: String) : Data
fun getDisplayString(data: Data) =
when(data) {
is NameData -> data.value
is PhoneData -> "${data.type} : ${data.value}"
is EmailData -> "${data.type} : ${data.value}"
else -> throw IllegalArgumentException("Unknown data")
}
getDisplayString 함수에서 어떤 데이터 타입이 올지 모르니 else를 추가해줘야 한다.
sealed 클래스를 적용해보면..
sealed class Data {
class NameData(val value: String) : Data()
class PhoneData(val value: String, val type: String) : Data()
class EmailData(val value: String, val type: String) : Data()
}
fun getDisplayString(data: Data) =
when(data) {
is Data.NameData -> data.value
is Data.PhoneData -> "${data.type} : ${data.value}"
is Data.EmailData -> "${data.type} : ${data.value}"
// else를 사용하지 않아도 된다.
}
fun main(args: Array<String>) {
val tempData = Data.PhoneData("01011112222", "휴대폰")
println(getDisplayString(tempData))
}
Data 클래스에 새로운 NickNameData가 추가된다고 하면..
sealed class Data {
// ...
class NickNameData(val value: String) : Data()
}
fun getDisplayString(data: Data) =
when(data) { // <-- NickNameData의 분기나, else문을 추가하라고 에러가 발생한다.
is Data.NameData -> data.value
is Data.PhoneData -> "${data.type} : ${data.value}"
is Data.EmailData -> "${data.type} : ${data.value}"
// else를 사용하지 않아도 된다.
}
다른 파일에서 Data 클래스를 상속하려고 하면 에러가 발생한다. 즉, 같은 파일내에서만 sealed class를 상속한 클래스를 정의 할 수 있다.
- sealed class는 private 생성자를 가진다.
위 예시처럼 클래스를 중첩하지 않고 아래와 같이 사용할 수 있다.(data 클래스도 사용이 가능하다. ) - 코틀린 1.1부터..
sealed class Data
data class NameData(val value: String) : Data()
data class PhoneData(val value: String, val type: String) : Data()
data class EmailData(val value: String, val type: String) : Data()
data class NickNameData(val value: String, val type: String) : Data()
fun getDisplayString(data: Data) =
when(data) {
// "Data."이 제거됐다.
is NameData -> data.value
is PhoneData -> "${data.type} : ${data.value}"
is EmailData -> "${data.type} : ${data.value}"
is NickNameData -> data.value
// else를 사용하지 않아도 된다.
}
sealed interface는 만들 수 없다.