Kotlin에서는 object
키워드를 다양한 상황에서 사용하지만 모든 경우 클래스를 정의하면서 동시에 instance를 생성한다는 공통점이 있다.
object 키워드를 사용하는 여러 상황을 살펴보자.
객체지향 시스템을 설계하다 보면 인스턴스가 하나만 필요한 클래스가 유용한 경우가 많다. 자바에서는 보통 클래스의 생성자를 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 인스턴스를 만드는 방법으로는 객체 선언이 가장 좋은 방법이다.