본문 바로가기
kotlin

Kotlin 자세히 알아보기 - companion object, sealed classes

by Gil 2019. 8. 11.
728x90

1. companion object

  • class 내에 정의할 수 있음
  • java에서처럼 Class.TYPE 형태로 직접 접근 가능
  • static은 아님
    • companion 변수는 private static final 이다. 따라서 외부 접근이 가능하도록 public final get*() 메서드가 생성된다. 
      (아래 이미지 참조)

kotlin companion 변수

 

Decompile java 에서 type변수 
Decompile java 에서 자동생성된 getType()

class Sample {
   val name: String = "Name"
   
   companion object {
        val type: Int = 0
        
        fun isTypeZero(): Boolean {
        	return type == 0
        }
    }
}    

 

2. companion object 접근하기

- kotlin vs java

  kotlin java
 

// 변수 접근
Sample.type

// function 접근
Sample.isTypeZero()

// 변수 접근
Sample.Companion.getType();

// function 접근
Sample.Companion.isTypeZero()


- java에서 Companion 사용하지 않고, java static 변수처럼 접근하려면?

변수 : const / @JvmField
function : @JvmStatic (@JvmStatic은 class에서는 사용가능하지만, interface에서는 사용불가능하다)

class Base {
    companion object {
      const val TYPE: Int = 0
      @JvmField val NAME: String = "Name"
      @JvmStatic fun isTypeZero(): Boolean {
          return TYPE == 0
      }
    } 
}    


- Companion 말고 다른 이름으로 접근하기

class MyClass {
    companion object Factory {
    	fun create(): MyClass = MyClass()
    }
}    

kotlin에서 접근 시
MyClass.create()

java에서 접근 시
MyClass.Factory.create()

 


3. Sealed Classes

  • Sealed class와 그걸 상속받는 클래스는 하나의 파일 안에 정의 되어야 한다
  • abstract 메소드를 생성할 수 있음 (일반 클래스에서는 안됨)
sealed class Sample {
    data class Num : Sample()
    data class Num2 : Sample()
    
    abstract fun printA()
}    

<활용 예제 1>
(참고로 eval() 함수는 문자열(expression)을 코드로 인식하게 하는 함수입니다)

/* 클래스 정의 */
sealed class Expr(val name: String)
class Const(val number: Double) : Expr("")
data class Sum(val e1: Expr, val e2: Expr) : Expr("")
object NotANumber : Expr("")


/* 함수 정의 */
fun eval(expr: Expr): Double = when(expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
    // 위의 모든 경우의 수가 있어서 'else' 로 갈 일 없음 
    // (위의 Expr sealed class 상속받은 모든 형태가 있음)
}    

/* 호출 */
fun text() {
    println(eval(Sum(Const(0.0), const(1.0))))
}

 

<활용 예제 2>

sealed class A
class B : A() {
    fun printB() {
    	println("class B")
    }
}
class C : A() {
	fun printC() {
    	println("class C")
    }
}

fun test() {
    print(B())
    print(c())
}

private fun print(a: A) {
    when(a) {
        is B -> a.printB()
    	is C -> a.printC()
    }
}    

 

 

 

[참고자료 출처]
Udemy 강좌 (안드로이드 공식 언어 : 코틀린(Kotlin) 시작하기)