이 튜토리얼에서는 Kotlin Sealed Class에 대해 살펴보겠습니다. 그것들은 무엇이며, 그들의 용도는 무엇인가요? 아래에서 이 모든 것에 대해 다룰 것입니다.
Kotlin Sealed Class
초보자 용어로 말하면 이름에서 알 수 있듯이, sealed 클래스는 밀봉되거나 닫혀 있어서 제한되어 있습니다. sealed 클래스는 객체 또는 값이 한 유형 중 하나에만 속할 수 있도록 하는 제한된 클래스 계층을 나타내기 위해 사용됩니다. 따라서 유형 계층을 고정시킵니다. sealed 클래스는 주어진 값이 주어진 옵션 세트 중 하나에만 속할 것을 알고 있는 경우에 일반적으로 사용됩니다.
Kotlin Sealed Classes 구현
Kotlin에서 sealed 클래스는 다음과 같이 구현됩니다.
sealed class A{
class B : A()
class C : A()
}
sealed 클래스를 지정하려면 수정자 sealed
를 추가해야 합니다. sealed 클래스는 인스턴스화될 수 없습니다. 따라서 암시적으로 추상화됩니다. 다음은 작동하지 않습니다.
fun main(args: Array<String>)
{
var a = A() //compiler error. Class A cannot be instantiated.
}
sealed 클래스의 생성자는 기본적으로 비공개입니다. sealed 클래스의 모든 하위 클래스는 동일한 파일 내에서 선언되어야 합니다. sealed 클래스는 컴파일 시간에 유형의 집합을 제한하여 유형 안전성을 보장하는 데 중요합니다.
sealed class A{
class B : A()
{
class E : A() //this works.
}
class C : A()
init {
println("sealed class A")
}
}
class D : A() //this works
{
class F: A() //This won't work. Since sealed class is defined in another scope.
}
생성자로 봉인된 클래스를 만듭니다.
sealed class A(var name: String){
class B : A("B")
class C : A("C")
}
class D : A("D")
fun main(args: Array<String>) {
var b = A.B()
var d = D()
}
봉인된 클래스에 데이터 클래스와 오브젝트를 추가합니다.
fun main(args: Array<String>) {
val e = A.E("Anupam")
println(e) //prints E(name=Anupam)
var d = A.D
d.name() //prints Object D
}
sealed class A{
class B : A()
class C : A()
object D : A()
{
fun name()
{
println("Object D")
}
}
data class E(var name: String) : A()
}
열거형과 봉인된 클래스의 차이
Kotlin에서, 봉인된 클래스는 열거형 클래스의 강화된 버전으로 볼 수 있습니다. 봉인된 클래스는 다른 유형의 인스턴스를 생성할 수 있게 해줍니다. 이는 열거형이 모든 열거형 상수에 동일한 유형을 사용하도록 제한하는 것과 다릅니다. 열거형 클래스에서는 다음과 같은 작업이 불가능합니다.
enum class Months(string: String){
January("Jan"), February(2),
}
열거형 클래스에서는 모든 상수에 대해 단일 유형만 허용됩니다. 여기서 봉인된 클래스가 여러 인스턴스를 허용함으로써 우리를 구해주는 것입니다.
sealed class Months {
class January(var shortHand: String) : Months()
class February(var number: Int) : Months()
class March(var shortHand: String, var number: Int) : Months()
}
봉인된 클래스의 이러한 기능을 프로젝트에서 어떻게 사용할 수 있을까요? 뉴스 피드와 같은 애플리케이션에서 아래와 같이 상태, 이미지, 비디오 게시물에 대한 세 가지 다른 클래스 유형을 만들 수 있습니다. 이는 열거형 클래스로는 불가능합니다.
sealed class Post
{
class Status(var text: String) : Post()
class Image(var url: String, var caption: String) : Post()
class Video(var url: String, var timeDuration: Int, var encoding: String): Post()
}
봉인된 클래스와 when
봉인된 클래스는 각 하위 클래스와 해당 유형이 경우로 작동하기 때문에 일반적으로 `when` 문과 함께 사용됩니다. 또한, 봉인된 클래스가 유형을 제한한다는 사실을 알고 있습니다. 따라서 `when` 문의 `else` 부분은 쉽게 제거할 수 있습니다. 아래 예제는 동일한 것을 보여줍니다.
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
class Rectangle(var length: Int, var breadth: Int): Shape()
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
is Shape.Rectangle -> println("Rectagle area is ${e.length*e.breadth}")
}
아래의 코드에서 `eval` 함수를 실행해 봅시다.
fun main(args: Array) {
var circle = Shape.Circle(4.5f)
var square = Shape.Square(4)
var rectangle = Shape.Rectangle(4,5)
eval(circle)
eval(square)
eval(rectangle)
//eval(x) //컴파일 시 오류.
}
//다음이 콘솔에 출력됩니다:
//원의 면적은 63.585입니다
//정사각형의 면적은 16입니다
//직사각형의 면적은 20입니다
참고: `is` 수정자는 클래스가 다음 유형인지 확인합니다. `is` 수정자는 클래스에만 필요합니다. Kotlin 객체에는 아래와 같이 필요하지 않습니다:
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
object Rectangle: Shape()
{
var length: Int = 0
var breadth : Int = 0
}
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
Shape.Rectangle -> println("Rectangle area is ${Shape.Rectangle.length*Shape.Rectangle.breadth}")
}
여기서 코틀린 봉인된 클래스 튜토리얼을 마칩니다. 참고 자료: Kotlin 문서
Source:
https://www.digitalocean.com/community/tutorials/kotlin-sealed-class