Skip to content

중급: 객체

이 챕터에서는 객체 선언을 탐색하여 클래스에 대한 이해를 넓힐 것입니다. 이 지식은 프로젝트 전반에 걸쳐 동작을 효율적으로 관리하는 데 도움이 될 것입니다.

객체 선언

코틀린에서는 객체 선언을 사용하여 단일 인스턴스를 가진 클래스를 선언할 수 있습니다. 즉, 클래스를 선언하는 동시에 단일 인스턴스를 생성합니다. 객체 선언은 프로그램을 위한 단일 참조 지점으로 사용할 클래스를 만들거나 시스템 전반에 걸쳐 동작을 조정하려는 경우에 유용합니다.

TIP

쉽게 접근할 수 있는 단 하나의 인스턴스만 있는 클래스를 싱글톤이라고 합니다.

코틀린의 객체는 **지연 초기화(lazy)**되므로, 접근될 때만 생성됩니다. 또한 코틀린은 모든 객체가 스레드로부터 안전한 방식으로 생성되도록 보장하므로, 이를 수동으로 확인할 필요가 없습니다.

객체 선언을 생성하려면 object 키워드를 사용합니다:

kotlin
object DoAuth {}

object 이름 뒤에 중괄호 {}로 정의된 객체 본문 내에 모든 프로퍼티 또는 멤버 함수를 추가합니다.

NOTE

객체는 생성자를 가질 수 없으므로, 클래스처럼 헤더를 가지지 않습니다.

예를 들어, 인증을 담당하는 DoAuth라는 객체를 만들고 싶다고 가정해 봅시다:

kotlin
object DoAuth {
    fun takeParams(username: String, password: String) {
        println("input Auth parameters = $username:$password")
    }
}

fun main(){
    // The object is created when the takeParams() function is called
    DoAuth.takeParams("coding_ninja", "N1njaC0ding!")
    // input Auth parameters = coding_ninja:N1njaC0ding!
}

객체에는 takeParams라는 멤버 함수가 있으며, 이 함수는 usernamepassword 변수를 매개변수로 받아 콘솔에 문자열을 반환합니다. DoAuth 객체는 이 함수가 처음 호출될 때만 생성됩니다.

NOTE

객체는 클래스와 인터페이스를 상속할 수 있습니다. 예시:

kotlin

interface Auth {

    fun takeParams(username: String, password: String)

}

object DoAuth : Auth {

    override fun takeParams(username: String, password: String) {

        println("input Auth parameters = $username:$password")

    }

}

데이터 객체

객체 선언의 내용을 더 쉽게 출력할 수 있도록 코틀린에는 데이터 객체가 있습니다. 초급 가이드에서 배운 데이터 클래스와 유사하게, 데이터 객체는 toString()equals()와 같은 추가 멤버 함수를 자동으로 제공합니다.

NOTE

데이터 클래스와 달리 데이터 객체는 단일 인스턴스만 가지며 복사할 수 없으므로, copy() 멤버 함수를 자동으로 제공하지 않습니다.

데이터 객체를 생성하려면 객체 선언과 동일한 구문을 사용하지만 data 키워드를 접두사로 붙입니다:

kotlin

data object AppConfig {}

예시:

kotlin

data object AppConfig {

    var appName: String = "My Application"

    var version: String = "1.0.0"

}



fun main() {

    println(AppConfig)

    // AppConfig

    

    println(AppConfig.appName)

    // My Application

}

데이터 객체에 대한 자세한 내용은 를 참조하세요.

동반 객체

코틀린에서 클래스는 객체, 즉 동반 객체를 가질 수 있습니다. 클래스당 하나의 동반 객체만 가질 수 있습니다. 동반 객체는 클래스가 처음 참조될 때만 생성됩니다.

동반 객체 내에 선언된 모든 프로퍼티나 함수는 모든 클래스 인스턴스에서 공유됩니다.

클래스 내에 동반 객체를 생성하려면 객체 선언과 동일한 구문을 사용하지만 companion 키워드를 접두사로 붙입니다:

kotlin

companion object Bonger {}

동반 객체는 이름을 가질 필요가 없습니다. 이름을 정의하지 않으면 기본값은 Companion입니다.

동반 객체의 프로퍼티나 함수에 접근하려면 클래스 이름을 참조하세요. 예시:

kotlin
class BigBen {
    companion object Bonger {
        fun getBongs(nTimes: Int) {
            repeat(nTimes) { print("BONG ") }
            }
        }
    }

fun main() {
    // Companion object is created when the class is referenced for the
    // first time.
    BigBen.getBongs(12)
    // BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG 
}

이 예시는 Bonger라는 동반 객체를 포함하는 BigBen이라는 클래스를 생성합니다. 동반 객체는 정수를 받아 해당 정수만큼 "BONG"을 콘솔에 출력하는 getBongs()라는 멤버 함수를 가집니다.

main() 함수에서 getBongs() 함수는 클래스 이름을 참조하여 호출됩니다. 이 시점에 동반 객체가 생성됩니다. getBongs() 함수는 매개변수 12와 함께 호출됩니다.

자세한 내용은 를 참조하세요.

연습

연습 1

커피숍을 운영하며 고객 주문을 추적하는 시스템이 있습니다. 아래 코드를 참고하여 main() 함수에 있는 다음 코드가 성공적으로 실행되도록 두 번째 데이터 객체 선언을 완성하세요:

|---|---|

kotlin
interface Order {
    val orderId: String
    val customerName: String
    val orderTotal: Double
}

data object OrderOne: Order {
    override val orderId = "001"
    override val customerName = "Alice"
    override val orderTotal = 15.50
}

data object // Write your code here

fun main() {
    // Print the name of each data object
    println("Order name: $OrderOne")
    // Order name: OrderOne
    println("Order name: $OrderTwo")
    // Order name: OrderTwo

    // Check if the orders are identical
    println("Are the two orders identical? ${OrderOne == OrderTwo}")
    // Are the two orders identical? false

    if (OrderOne == OrderTwo) {
        println("The orders are identical.")
    } else {
        println("The orders are unique.")
        // The orders are unique.
    }

    println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}")
    // Do the orders have the same customer name? false
}

|---|---|

kotlin
interface Order {
    val orderId: String
    val customerName: String
    val orderTotal: Double
}

data object OrderOne: Order {
    override val orderId = "001"
    override val customerName = "Alice"
    override val orderTotal = 15.50
}

data object OrderTwo: Order {
    override val orderId = "002"
    override val customerName = "Bob"
    override val orderTotal = 12.75
}

fun main() {
    // 각 데이터 객체의 이름 출력
    println("Order name: $OrderOne")
    // Order name: OrderOne
    println("Order name: $OrderTwo")
    // Order name: OrderTwo

    // 두 주문이 동일한지 확인
    println("Are the two orders identical? ${OrderOne == OrderTwo}")
    // Are the two orders identical? false

    if (OrderOne == OrderTwo) {
        println("The orders are identical.")
    } else {
        println("The orders are unique.")
        // The orders are unique.
    }

    println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}")
    // Do the orders have the same customer name? false
}

연습 2

Vehicle 인터페이스를 상속하는 객체 선언을 생성하여 고유한 차량 유형인 FlyingSkateboard를 만드세요. main() 함수에 있는 다음 코드가 성공적으로 실행되도록 객체에 name 프로퍼티와 move() 함수를 구현하세요:

|---|---|

kotlin
interface Vehicle {
    val name: String
    fun move(): String
}

object // Write your code here

fun main() {
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}")
    // Flying Skateboard: Glides through the air with a hover engine
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}")
    // Flying Skateboard: Woooooooo
}

|---|---|

kotlin
interface Vehicle {
    val name: String
    fun move(): String
}

object FlyingSkateboard : Vehicle {
    override val name = "Flying Skateboard"
    override fun move() = "Glides through the air with a hover engine"

   fun fly(): String = "Woooooooo"
}

fun main() {
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}")
    // 플라잉 스케이트보드: 호버 엔진으로 공중을 활공합니다
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}")
    // 플라잉 스케이트보드: 우워어어어어
}

연습 3

온도를 기록하고 싶은 앱이 있습니다. 클래스 자체는 정보를 섭씨로 저장하지만, 화씨로 인스턴스를 쉽게 생성할 수 있는 방법을 제공하고 싶습니다. main() 함수에 있는 다음 코드가 성공적으로 실행되도록 데이터 클래스를 완성하세요:

힌트

동반 객체를 사용하세요.

|---|---|

kotlin
data class Temperature(val celsius: Double) {
    val fahrenheit: Double = celsius * 9 / 5 + 32

    // Write your code here
}

fun main() {
    val fahrenheit = 90.0
    val temp = Temperature.fromFahrenheit(fahrenheit)
    println("${temp.celsius}°C is $fahrenheit °F")
    // 32.22222222222222°C is 90.0 °F
}

|---|---|

kotlin
data class Temperature(val celsius: Double) {
    val fahrenheit: Double = celsius * 9 / 5 + 32

    companion object {
        fun fromFahrenheit(fahrenheit: Double): Temperature = Temperature((fahrenheit - 32) * 5 / 9)
    }
}

fun main() {
    val fahrenheit = 90.0
    val temp = Temperature.fromFahrenheit(fahrenheit)
    println("${temp.celsius}°C is $fahrenheit °F")
    // 32.22222222222222°C는 90.0°F입니다
}

다음 단계

중급: 공개 및 특별 클래스