Sealed Class

이창민·2022년 1월 6일
0

sealed class

Sealed Class를 사용하면 컴파일시에 상속받는 Child class가 무엇 있는지 알아 제한된다.
같은 패키지 안에 있는 child만으로 제한된다.

sealed class Color

object Red: Color()
object Green: Color()
object Blue: Color()

정의는 sealed class className으로 위와 같이 할 수 있다.
sealed 키워드를 붙이면 abstract 클래스가 된다.

val color: Color = Red

위와 같이 객체를 생성할 수 있다.

object로 상속받기

sealed class를 위와 같이 object class로 상속할 경우 singleton 패턴이 적용된다.

class로 상속받기

sealed class Color

class Red: Color()
class Green: Color()
class Blue: Color()

위와 같이 사용할 경우 equals, hashCode 를 오버라이드 해야한다.

그럼 왜 equals와 hash 함수를 오버라이드 해야할까

class를 상속할 때 최상위 객체인 Any에는 override가 가능한 3가지 함수가 존재한다.
equals, hashcode, toString 함수이다.
예를들어 product를 아래와 같이 정의한다.

class Product(val categoryLabel: String, val name: String =""){
    
    }

이후 아래와 같이 사용하면

toString

val product = Product("패션, "롱 패딩")
println("$product")

우리가 원하는 categoryLabel: 패션, name: 롱 패딩 이런식으로 출력되지 않고
Product@어쩌구저쩌구 가 나올 것이다.
이는 우리이게 의미있는 정보가 아니다. 그러면 오버라이드를 해야한다

equals

val product1 = Product("패션, "롱 패딩")
val product2 = Product("패션, "롱 패딩")
println(product1 == product2)

위의 결과는 false가 나온다.
우리는 true를 원할 것인데 false가 나온다.
같은 정보를 가지고 있으니 true라고 판단하고 싶다 false이니
override하면 된다.

hashCode

val product1 = Product("패션, "롱 패딩")
val product2 = Product("패션, "롱 패딩")
val productSet = hashSetOf(product1)
println(productSet.contains(product2))

위의 결과는 false이다. 왜 false일까
hashSet은 hashCode를 고유한 식별자로 사용해 검색 최적화를 한다.
객체의 hashCode를 비교하고 해시 코드가 같은 경우에만 실제 값을 비교한다.
그러면 우리는 위의 경우 어떻게 오버라이드 해야할까.

class Product(val categoryLabel: String, val name: String =""){
	override fun hashCode(): Int{
    	return categoryLabgel.hashCode() + name.hashCode()
    }

위와 같이 오버라이드 하면 결과가 true가 된다.

결론적으로 data를 관리하는 class일 경우 toString, equals, hashCode를 오버라이드해야한다.

class Product(val categoryLabel: String, val name: String =""){
	override fun toString(): String{
    	~~~
    }
    
    override fun equals(other: Any): Boolean{
    	~~~
    }
    
    override fun hashCode(): Int{
    	return categoryLabgel.hashCode() + name.hashCode()
    }

코틀린을 사용할 때 class 앞에 data 키워드를 추가하면 위 3가지 함수를 오버라이드 하지 않아도 된다.

selaed class 이점

when을 사용할 때 특징이 나타난다.

fun log(e: Error) = when(e) {
    is FileReadError -> { println("Error while reading file ${e.file}") }
    is DatabaseError -> { println("Error while reading from database ${e.source}") }
    RuntimeError ->  { println("Runtime error") }
    // the `else` clause is not required because all the cases are covered
}

모든 경우를 포함할 경우 else가 필요 없다.

참고자료

https://codechacha.com/ko/kotlin-sealed-classes/
https://kotlinworld.com/m/165
https://kotlinlang.org/docs/sealed-classes.html#sealed-classes-and-when-expression

profile
android 를 공부해보아요

0개의 댓글