[Kotlin] Kotlin엔 static 키워드가 없다

Chloe Choi·2021년 1월 22일
0

Kotlin

목록 보기
5/11

원글

From Java to Kotlin: life without static
Kotlin엔 static 키워드가 없습니다. 그럼 코틀린에서는 static을 대체하기 위해 무엇을 써야할까요?

이를 대체하기 위해 선택할 수 있는 옵션은 다음과 같습니다.

  • Top-level functions
  • Top-level constants
  • Companion object functions
  • Object instance

이런 선택지들이 있는데, 언제 어떤 옵션을 선택해야할까요?

Top-level functions & properties

Function main()

자바에서는 main 함수를 작성할 때 많은 보일러 플레이트 코드가 있습니다! 클래스 안에 public static void main(String[] args)와 같이 작성해야 해요. 코틀린에서는 Top-level function으로 구현해주면 끝 입니다!

Get rid of utility classes

많은 Util, Helper 클래스를 작성한 경험이 있죠? Util 클래스 안에 static 키워드로 범용적인 메소드를 구현하곤 했습니다. Kotlin에서는 그냥 Top-level function으로 작성해주면 됩니다! 그러고 해당 패키지 내부에서 사용하거나, 다른 패키지에서 해당 Top-level function을 import하면 사용 가능합니다~ ㅎㅎ

Java

public class StringUtils {
  private StringUtils() { /* Forbid instantiation of utility class */ }   

  public static int lowerCaseCount(String value) {
      return value.chars().reduce(0, 
              (count, current) -> count + (Character.isLowerCase(current) ? 1 : 0));
  }
}

Kotlin

package toplevel

fun lowerCaseCount(value: String): Int = value.count { it.isLowerCase() }

Constants

프로퍼티 또한 Top-level에 작성할 수 있습니다. 물론 immutable하게 선언을 해야겠죠?

Private top-level functions

위 Get rid of utility classes의 lowerCaseCount 메소드가 한 클래스에서만 필요하다면 Java에서는 다음과 같이 구현할 수 있겠죠?

public class MyClass {
  private String myString;
  public void doSomething() {
    int count = lowerCaseCount(myString);
    ...
  }
  private static int lowerCaseCount(String value) { ... } // private static pure function
}

코틀린에서는 해당 static 메소드를 클래스 밖으로 빼서 해당 파일내에 priate top-level function으로 구현해 해당 파일 내에서만 접근가능하게 할 수 있습니다!

Object singletons

코틀린에서는 싱글톤 패턴을 Object 키워드로 제공합니다! 따라서, 자바에서 싱글톤 패턴 구현을 위해 static 키워드를 썼다면 Object 키워드로 대체할 수 있죠~

Companion objects

해당 클래스의 함수임을 명시적으로 표현하고 싶은 경우에는 어떻게 해야할까요?(ex. Math.abs()) 이럴 땐 Companion object를 사용하면 됩니다! (static에 대한 대체로 무조건적으로 Companion object을 사용하는 사람들이 있는데 이런건 잘못된 사용입니다,,)

Static factory methods

Companion objects는 클래스 내부에 정의된 Singletone value에요. Companion object 내 멤버들은 클래스 이름으로 호출할 수 있습니다. 게다가 Companion obeject는 클래스 인스턴스의 private 멤버들에 접근할 수 있기 때문에 팩토리 메소드에 !특히! 유용합니다 ㅎㅎ

class Rocket private constructor() {
  private fun attachPropellers() { ... }

  companion object {
    fun build(): Rocket {
      val rocket = Rocket()  // can call private constructor
      rocket.attachPropellers() // can call private function
      return rocket
    }
  }
}

fun main() {
  val rocket = Rocket.build() // Companion function called using the accompanied class name
}

정리

profile
똑딱똑딱

0개의 댓글