with ChatGPT/코틀린 with ChatGPT
[코틀린 with ChatGPT #10] 코틀린의 클래스(Class)와 객체(Object)를 어떻게 정의하고 사용하는가?
dev_writer
2025. 3. 24. 09:00
with ChatGPT 시리즈는 ChatGPT의 내용과 개인의 생각을 토대로 학습해 보는 컨텐츠입니다.
Kotlin은 객체지향의 기본 개념을 간결하게 표현할 수 있도록 설계된 언어입니다.
Java보다 코드량이 훨씬 적고, 클래스의 구조를 명확하게 표현할 수 있다는 장점이 있습니다.
이번 글에서는 Kotlin에서 클래스와 객체를 어떻게 정의하고 사용하는지, 그리고 자바와의 차이점은 무엇인지 살펴보겠습니다.
🔹 1. 클래스 정의와 생성자
Kotlin에서는 클래스 선언과 생성자를 한 줄로 표현할 수 있습니다.
class User(val name: String, val age: Int)
- val: 읽기 전용 (immutable) 프로퍼티
- var: 읽고 쓰기 가능한 (mutable) 프로퍼티
- 생성자 파라미터는 자동으로 클래스 프로퍼티로 선언
자바 코드로 따지면 다음과 같습니다:
public class User {
private final String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
✅ 클래스 본문과 init 블록
class User(val name: String) {
init {
println("사용자가 생성됨: $name")
}
fun greet() {
println("안녕하세요, $name입니다.")
}
}
- init 블록은 주 생성자 호출 직후 실행되는 초기화 코드
🔹 2. 객체 생성 및 기본값
✅ 객체 생성은 new 없이
val user = User("Alice", 30)
- Kotlin에서는 new 키워드 없이 바로 인스턴스 생성 가능
✅ 기본값이 있는 생성자
class ApiResponse(val status: String = "OK", val code: Int = 200)
val response = ApiResponse(code = 404)
- 불필요한 생성자 오버로딩 없이 다양한 초기화 가능
- Named Argument와 함께 사용하면 실무에서 매우 유용
🔹 3. 접근 제어자와 프로퍼티 캡슐화
✅ Kotlin의 기본 접근자는 public이지만, 실무에서는 캡슐화가 중요합니다.
class Account(private val id: String, var balance: Int) {
fun deposit(amount: Int) {
balance += amount
}
}
- id는 외부에서 접근 불가능
- balance는 외부에서 읽고 쓸 수 있음 → 필요에 따라 private set으로 보호 가능
class SafeAccount(val id: String, balance: Int) {
var balance: Int = balance
private set
}
- 위와 같이 하면 읽기는 가능하지만, 클래스 외부에서 balance 변경 불가
🔹 4. companion object: Java의 static을 대체하는 Kotlin 방식
Kotlin에서는 static 키워드가 없고, 대신 정적 멤버는 companion object를 사용합니다.
class Logger {
companion object {
fun log(message: String) {
println("LOG: $message")
}
}
}
Logger.log("Hello") // static처럼 호출 가능
- companion object는 해당 클래스에 소속된 싱글턴 객체
- 내부적으로는 Logger.Companion.log(...) 형태지만, 직접 Logger.log()처럼 호출 가능
✅ Java의 static과 Kotlin companion object 비교
항목 | Java (static) | Kotlin (companion object) |
선언 방식 | static 키워드 | companion object 블록 |
접근 방식 | ClassName.method() | 동일 (ClassName.method()) |
객체인가? | ❌ 아님 | ✅ 객체로 존재함 |
인터페이스 구현 | 불가 | 가능 |
✅ 인터페이스 구현 예시
interface Factory<T> {
fun create(): T
}
class User(val name: String) {
companion object : Factory<User> {
override fun create(): User = User("default")
}
}
- companion object는 객체이기 때문에 인터페이스를 구현할 수 있음
- 이 패턴은 Spring에서 @Converter, @Deserializer 같은 구조 구현 시 유용
🚀 결론
기능 | Kotlin 방식 | 특징 |
클래스 정의 | class User(val name: String) | 생성자와 프로퍼티를 간결하게 표현 |
객체 생성 | User("Alice") | new 키워드 없음 |
초기화 블록 | init { ... } | 생성자 직후 실행 |
프로퍼티 접근 제어 | private, private set 등 | 읽기/쓰기 범위를 명확히 제어 |
정적 멤버 | companion object | Java의 static을 대체, 객체 기반 |
🤔 추가로 생각해 볼 질문들
- Kotlin에서 private set을 활용하면 어떤 상황에서 유용할까?
- companion object와 object 키워드는 어떤 차이를 가질까?
- Kotlin에서는 정적 유틸리티 함수는 어떻게 관리하는 것이 좋을까? (top-level function vs companion object)
- 여러 개의 companion object를 허용하지 않는 이유는 무엇일까?
- companion object와 Java static 유틸리티 클래스의 실제 메모리 차이는?