[Kotlin] Kotlin식 문법: 클래스, 객체, 인터페이스 -8

박준규·2022년 3월 10일
0

코틀린

목록 보기
17/19

Object keyword: 클래스 선언과 인스턴스 생성

Kotlin에서는 object키워드를 다양한 상황에서 사용하지만 모든 경우 클래스를 정의하면서 동시에 instance를 생성한다는 공통점이 있다.

object 키워드를 사용하는 여러 상황을 살펴보자.

  • 객체 선언은 싱글턴을 정의하는 방법 중 하나다.
  • companion object는 instance 메소드는 아니지만 어떤 class와 관련 있는 method와 factory method를 담을 때 쓰인다. companion object method에 접근할 때는 동반 객체가 포함된 class의 이름을 사용할 수 있다.
  • 객체 식은 자바의 anonymous inner class 대신 쓰인다.

객체 선언: 싱글턴을 쉽게 만들기

객체지향 시스템을 설계하다 보면 인스턴스가 하나만 필요한 클래스가 유용한 경우가 많다. 자바에서는 보통 클래스의 생성자를 private으로 제한하고 정적인 field에 그 class의 유일한 객체를 저장하는 singleton Pattern을 통해 이를 구현한다.

그리고 kotlin의 경우 객체 기능을 통해 싱글턴을 언어에서 기본 지원한다. 객체 선언은 클래스 선언과 그 클래스에 속한 단일 instance의 선언을 합친 선언이다.

다음의 object를 살펴보자.

object Payroll {
    val allEmployee = arrayListOf<Person>()
    fun calculateSalary() {
        for (person in allEmployee) {
            // ~~~
        }
    }
}

data class person(
    val name: String? = null,
    val age: Int? = null,
    val position: String? = null
    val workingTimeMonthly: Int? = null
)

객체 선언은 object 키워드로 시작한다. 객체 선언은 클래스를 정의하고 그 클래스의 instance를 만들어서 변수에 저장하는 모든 작업을 단 한 문장으로 처리한다. 클래스와 마찬가지로 객체 선언 안에도 property, method, init block 등이 들어갈 수 있다. 하지만 생성자는 객제 선언에서 쓸 수 없다.

생성자는 object 클래스에서 왜 쓸 수 없을까?

왜냐하면 일반 class instance 와는 달리 singleton object는 객체 선언문이 있는 위치에서 생성자 호출 없이 즉시 만들어진다. 따라서 객체 선언에는 생성자 정의가 필요없다.

즉 일반 클래스는 생성자를 호출하고 instance가 만들어지는 반면 object는 생성자 호출 없이 instance가 만들지기 때문에 생성자를 사용할 수 없다.

object class는 변수와 마찬가지로 객체 선언에 사용한 이름 뒤에 마침표 .를 붙이면 객체에 속한 method나 property에 접근할 수 있다.

object Payroll {
    val allEmployees = arrayListOf<Person>()
    fun calculateSalary() {
        for (person in allEmployees) {
            println(person)
        }
    }
}

data class Person(
    val name: String? = null,
    val age: Int? = null,
    val position: String? = null,
    val workingTimeMonthly: Int? = null,
    val unitHourForSalary: Int? = null
)

fun main() = with(Payroll) {
    allEmployees.add(Person(
        name = "Junku",
        age = 19,
        position = "developer",
        workingTimeMonthly = 143,
        unitHourForSalary = 10000
    	)
   )
   calculateSalary()
   // Person(name=Junku, age=19, position=developer, workingTimeMonthly=143, unitHourForSalary=10000)
}

또한 객체 선언도 class나 interface를 상속할 수 있다. 프레임워크를 사용하기 위해 특정 인터페이스를 구현해야 하는데, 그 구현 내부에 다른 상태가 필요하지 않은 경우에 이런 기능이 유용하다. 예를 들어서 java.util.Comparator 인터페이스를 살펴보자.

Comparator 구현은 두 객체를 인자로 받아 그중 어느 객체가 더 큰지 알려주는 정수를 반환한다. Comparator 안에는 데이터를 저장할 필요가 없다. 따라서 어떤 클래스에 속한 객체를 비교할 때 사용하는 Comparator는 보통 클래스마다 하나씩 있으면 된다. 따라서 Comparator 인스턴스를 만드는 방법으로는 객체 선언이 가장 좋은 방법이다.

profile
'개발'은 '예술'이고 '서비스'는 '작품'이다

0개의 댓글