Kotlin의 sealed class, extensions 정리
08 Oct 2022패스트 캠퍼스 실무 프로젝트로 배우는 Kotlin & Spring 강의 정리
Sealed class
- 하나의 상위 클래스나 인터페이스에서 하위 클래스의 정의를 제한할 수 있는 방법
- sealed 클래스는 같은 패키지나 모듈에서만 하위 클래스를 정의할 수 있음
- 아래의 코드에서는 Developer 클래스를 상속하는 클래스는 두 개 뿐이지만, when 식에서
else
구문이 없으면 컴파일 에러 발생
abstract class Developer {
abstract val name: String
abstract fun code(language: String)
}
data class BackendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println("저는 백엔드 개발자입니다. $language 를 사용합니다.")
}
}
data class FrontendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println("저는 프론트엔드 개발자입니다. $language 를 사용합니다.")
}
}
object DeveloperPool {
val pool = mutableMapOf<String, Developer>()
fun add(developer: Developer) = when(developer) {
is BackendDeveloper -> pool[developer.name] = developer
is FrontendDeveloper -> pool[developer.name] = developer
else -> println("지원하지 않는 개발자입니다.")
}
fun get(name: String) = pool[name]
}
sealed
키워드를 이용하면 어떤 하위 클래스가 있는지 컴파일러가 판단할 수 있음- sealed 클래스를 상속한 하위 클래스가 있는데 when 식에서 정의되지 않으면 컴파일 에러 발생
sealed class Developer {
abstract val name: String
abstract fun code(language: String)
}
data class BackendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println("저는 백엔드 개발자입니다. $language 를 사용합니다.")
}
}
data class FrontendDeveloper(override val name: String) : Developer() {
override fun code(language: String) {
println("저는 프론트엔드 개발자입니다. $language 를 사용합니다.")
}
}
object DeveloperPool {
val pool = mutableMapOf<String, Developer>()
fun add(developer: Developer) = when(developer) {
is BackendDeveloper -> pool[developer.name] = developer
is FrontendDeveloper -> pool[developer.name] = developer
}
fun get(name: String) = pool[name]
}
Extensions
- 상속이나 데코레이터 패턴 등의 디자인 패턴을 사용하지 않고도 클래스를 확장하게 하는 기능
fun {클래스}.{생성할 함수 이름}
fun String.first(): Char {
return this[0]
}
- 수신자 객체(Receiver Object)
- 확장 함수의
this
키워드는 수신자 객체와 일치
- 확장 함수의
- 확장하는 클래스에 동일한 이름의 메서드가 존재할 경우, 클래스의 멤버 함수가 우선시 됨
- 확장하는 클래스에 동일한 시그니처가 있는지 확인해야 함
- 수신자 객체가 nullable한 경우 확장 함수에서 null에 대한 처리를 하면 null 연산자 없이 사용 가능
class Example
fun Example?.printNullOrNotNull() {
if (this == null) println("Null")
else println("NotNull")
}
fun main() {
var example: Example? = null
example.printNullOrNotNull() // null 연산자 없이 사용, Null
example = Example()
example.printNullOrNotNull() // NotNull
}