object

object는 언제 사용하는가

싱글턴 구현하기

구현 방법

코틀린에서는 아래와 같은 방법으로 싱글턴을 정의 하는것을 object 선언이라고 부른다

object Payroll {

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

중첩 object를 사용한 구현 방법

클래스 안에서 object 선언을 할 수 있다

data class Person(val name: String) {
    
    object NameComparator: Comparator<Person> {
        override fun compare(p1: Person, p2: Person): Int{
            p1.name.compareTo(p2.name)
        }
    }
}
val persons = listOf(Person("Bob"), Person("Alice"))
println(persons.sortedWith(Person.NameComparator))

// 결과
[Person("Alice"), Person("Bob")]

companion object

코틀린은 자바 static 키워드를 지원하지 않는다. 대신 아래의 방법을 활용한다

중첩 object와 companion object 차이

중첩 object

class Outer {
    
    object NestedClass {
        val no: Int = 0
        fun myFun() {}
    }
}

fun main(args: Array<String>) {
    Outer.NestedClass.no
    Outer.NestedClass.myFun()
}

companion object

class Outer {

    companion object NestedClass {
        val no: Int = 0
        fun myFun() {}
    }

    // Outer 클래스 내부에서 자신의 클래스 멤버처럼 이용할 수 있다
    fun outerFun() {
        no
        myFun()
    }
}

fun main(args: Array<String>) {
    Outer.NestedClass.no
    Outer.NestedClass.myFun()

    // object 클래스명을 사용하지 않고 이용할 수 있다
    Outer.no
    Outer.myFun()
}

companion object 구현하기

부 생성자가 두개 있는 클래스

class User {

    val nickname: String
    
    constructor(email: String) {
        nickname = email.substringBefore('@')
    }
    
    constructor(facebookAccountId: Int) {
        nickname = getFacebookName(facebookAccountId)
    }
}

부생성자를 팩토리 메소드로 변경하기

class User private constructor(val nickname: String) {
    
    companion object {
        fun newSubscribingUser(email: String) = 
            User(email.substringBefore('@'))
        
        fun newFacebookUser(accountId: Int) = 
            User(getFacebookName(accountId))
    }
}
val subscribingUser = User.newSubscribingUser("bob@gamil.com")
val facebookUser = User.newFacebookUser(4)

Reference