Kotlin 기초정리 – data class, companion object, object class 에 대해 알아보자

seoyoon jungseoyoon jung
3 min read

1. data class – 데이터를 담는 그릇

Kotlin에서는 데이터를 담기 위한 클래스를 간단히 선언할 수 있습니다.
Java에서라면 getter, setter, equals(), hashCode(), toString() 등을 다 일일이 작성해야 했으나
Kotlin에서는 data class로 선언하면 자동 생성됩니다.

data class Ticket(
    val companyName: String,
    val name: String,
    var date: String,
    var seatNumber: Int    
)

class Ticket2(
    val companyName: String,
    val name: String,
    var date: String,
    var seatNumber: Int    
)

출력 비교

fun main() {
    val ticketA = Ticket("koreanAir", "sy", "2024-02-02", 14)
    val ticketB = Ticket2("koreanAir", "sy", "2024-02-02", 14)

    println(ticketA) // Ticket(companyName=koreanAir, name=sy, date=2024-02-02, seatNumber=14)
    println(ticketB) // Ticket2@3feba861 (메모리 주소 출력됨)
}

data class는 내용 중심이고, 일반 클래스는 객체 주소 중심!!

✨ 자동 생성되는 기능들

  • toString()

  • equals()

  • hashCode()

  • copy()

  • componentN()

이런 것들 때문에 데이터 중심 모델을 정의할 때 매우 유용하다고 합니다. (예: API 응답 DTO, DB Entity 등..)


2. companion object – Kotlin의 static 대체제

Java의 static 대신에 정적인 메소드나 정적인 변수를 선언할 때 사용합니다.
코틀린에서 클래스 레벨에서 공유되는 정적 멤버가 필요할 땐 companion object를 사용합니다.

기본 예제

class Book private constructor(
    val id: Int,
    val name: String
) {
    companion object {
        fun create() = Book(1, "animal")
    }
}

fun main() {
    val book = Book.Companion.create() // Companion 생략도 가능! -> Book.create()가 가능.
    println("${book.id} ${book.name}") // 1 animal
}

private constructor 를 추가해줌으로써 외부에서 직접 생성하지 못하게 막고,
companion object가 팩토리 역할을 대신해줍니다.


이름 있는 Companion Object

class Book private constructor(
    val id: Int,
    val name: String
) {
    companion object BookFactory {
        val myBook = "new book"
        fun create() = Book(0, myBook)
    }
}

Book.BookFactory.create()처럼 객체 이름으로 접근할 수 있습니다.


인터페이스 상속도 가능

interface IdProvider {
    fun getId(): Int
}

class Book private constructor(
    val id: Int,
    val name: String
) {
    companion object BookFactory : IdProvider {
        override fun getId(): Int = 444

        val myBook = "new book"
        fun create() = Book(getId(), myBook)
    }
}

fun main() {
    val book = Book.create()
    val bookId = Book.BookFactory.getId()
    println("${book.id} ${book.name}") // 444 new book
}

companion object인터페이스 구현, 싱글턴처럼 정적 접근, 팩토리 패턴 구현 모두 가능합니다.


3. object class – 싱글턴

Kotlin에서는 object 키워드를 사용해 단 하나의 인스턴스만 생성되는 클래스를 만들 수 있습니다.
즉, 앱 전역에서 공유가 가능한 싱글턴 객체를 말합니다.
팩토리/매니저 역할 등에 적합합니다.

object CarFactory {
    val cars = mutableListOf<Car>()

    fun makeCar(horsePower: Int): Car {
        val car = Car(horsePower)
        cars.add(car)
        return car
    }
}

data class Car(val horsePower: Int)

fun main() {
    val car1 = CarFactory.makeCar(10)
    val car2 = CarFactory.makeCar(200)

    println(car1) // Car(horsePower=10)
    println(car2) // Car(horsePower=200)
    println(CarFactory.cars.size) // 2
}

object는 클래스가 정의되자마자 메모리에 올라가며, 전역 싱글턴처럼 사용 가능합니다.


✨ 정리

문법 키워드역할
data class데이터 중심 클래스, 자동 생성 메서드 제공
companion object클래스 내부 정적 멤버, 팩토리 함수, 인터페이스 상속 가능
object (싱글턴)애플리케이션 전역에서 단일 인스턴스로 사용

✨ 요약

  • Kotlin은 보일러플레이트 코드 제거를 해줍니다.

  • Java에서 많이 사용했던 static, singleton, POJO 개념들이 더 간결하고 선언적으로 사용됩니다.

  • object 키워드는 싱글턴 객체를 만들기 위한 문법으로, 실행 시점에 단 한 번만 인스턴스가 생성되기 때문에 상태를 공유하기위한 객체를 정의할 때 매우 유용합니다.

0
Subscribe to my newsletter

Read articles from seoyoon jung directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

seoyoon jung
seoyoon jung