개요
이번 글에서는 코틀린의 객체지향 프로그래밍(OOP) 개념을 자바와 비교해서 정리해보려한다. 특히 자바에 익숙한 입장에서 코틀린의 클래스 선언, 생성자, 상속, 인터페이스, 싱글턴 객체, enum, data class 등의 구조를 학습해보자.
1. 클래스 선언 - 기본 구조와 생성자
자바에서는 클래스를 선언하고, 필드를 만들고, 생성자를 통해 초기화를 진행하는 방식이 일반적이다.
- 자바
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
- 코틀린
class Person(val name: String, val age: Int)
코틀린은 생성자를 클래스 선언부에 바로 작성 가능하다. 이를 주 생성자(Primary Constructor) 라고 한다.
val, var 를 붙이면 자동으로 멤버 변수 선언 + 초기화 까지 수행된다.
생성자 종류
주 생성자 + 부 생성자
- 주 생성자 (Primary Constructor): 클래스 선언부에서 정의
- 부 생성자 (Secondary Constructor): 클래스 본문 내부에서 constructor 키워드로 정의
class Person(val name: String) {
var age: Int = 0
// 부 생성자: name과 age 모두 받는 생성자
constructor(name: String, age: Int) : this(name) {
this.age = age
}
}
- 주 생성자는 name 하나만 받는 간단한 생성자이다.
- 부 생성자는 name과 age를 다 받고 싶을 때 사용하는데, 내부적으로 주 생성자(this(name)을 먼저 호출하고 추가로 age 값을 설정하는 구조이다
즉, 기본 구조를 재활용하면서 확장하는 방법이다.
default value를 이용한 기본 생성자
코틀린은 매개변수 자체에 기본 값을 줄 수 있다!
-> 굳이 부 생성자를 만들 필요가 없을 때가 많다.
class Person(val name: String, val age: Int = 0)
실무에서 쓰는 방식
data class User{
val name: String,
val age: Int = 0,
val email: String? = null
}
이렇게하면 다양한 생성자 조합이 없어도 모두 가능하다.
- User("버닝맨")
- User("버닝맨", 20)
- User("버닝맨", 20, "burningman@gamil.com")
2. 클래스 상속과 멤버 오버라이드 - open, override
자바에서는 클래스가 기본적으로 상속 가능하지만,
코틀린은 기본적으로 모든 클래스가 final 이기 때문에 상속을 원한다면 open 키워드를 붙여야한다.
open class Anmal {
open fun sound() {
println("소리를 낸다.")
}
}
class dog : Anmal() {
override fun sound() {
println("멍멍")
}
}
- open: 클래스나 함수의 상속 가능을 설정
- override: 부모 클래스의 함수 재정의
3. data clss - 데이터 객체 선언을 간결하게
자바에서 DTO, VO를 만들 때는 equals(), hashcode(), toString()을 수동으로 작성해야 하지만, 코틀린의 data class 는 자동 생성해준다.
data clss User(val name: String, val age: Int)
---
val user = User("버닝맨", 20)
val copied = user.copy(age = 30)
println(user) // User(name=버닝맨, age=20)
- equals(), hashCode(), toString() 자동 생성
- copy(), componentN() 등 구조 분해 지원 -> 구조 분해에 유용
4. object - 싱글톤 객체 선언
자바에서는 싱글톤을 만들기 위해 별도의 패턴을 구성해야했지만,
코틀린에서는 object 키워드 하나로 간단하게 싱글톤을 선언할 수 있다.
object Config {
val version = "1.0"
}
- 객체는 앱 전체에 하나만 존재함
- 클래스 선언과 동시에 인스턴스가 생성됨
5. interface - 인터페이스 구현
- 자바
public interface Worker {
void work();
}
- 코틀린
interface Worker {
fun work()
}
---
class Developer : Worker {
override fun work() {
println("개발 중")
}
}
- 코틀린에서는 fun 키워드를 이용해 메서드를 선언
- 클래스에서 구현할 때는 반드시 override fun 으로 명시
6. enum class - 열거형 선언
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
각 enum 값은 Direction.NORTH 처럼 사용한다.
enum class Status(val code: Int) {
SUCCESS(200),
ERROR(500)
}
생성자와 프로퍼티도 정의 가능하다.
마무리
요약
| 구분 | 자바 | 코틀린 |
| 클래스 | 기본 상속 가능 | 기본 final, open 키워드 필요 |
| 생성자 | 클래스 내부에 작성 | 클래스 선언부에 주 생성자 작성 가능 |
| 상속 | 자동 허용 | open 키워드 필요 |
| 싱글톤 | 별도 패턴 구현 | object 키워드 하나로 구현 |
| 데이터 객체 | 수동 구현 | data class로 자동 생성 |
| 인터페이스 | 구현 강제 | fun, override fun |
실습
// 인터페이스 정의
interface Worker {
fun work(): String
}
// 부모 클래스
open class Person(val name: String, val age: Int) {
open fun introduce(): String {
return "안녕하세요. 저는 $name이고 ${age}살 입니다."
}
}
// 자식 클래스
class Developer(name: String, age: Int, val language: String) : Person(name, age), Worker {
override fun work(): String {
return "$language 언어로 개발을 시작합니다."
}
override fun introduce(): String {
return super.introduce() + " 저는 개발자이고, $language 를 사용합니다."
}
}
// enum class
enum class LoginStatus(val code: Int) {
SUCCESS(200),
FAIL(401),
TIMEOUT(408)
}
// data class
data class User(val name: String, val job: String, val age: Int = 0)
// object
object Logger {
fun log(status: LoginStatus, message: String) {
println("[${status.name}] (${status.code}) $message")
}
}
fun main() {
val user = User("버닝맨", "Developer", 20)
val person = when (user.job) {
"Developer" -> Developer(user.name, user.age, "Kotlin")
else -> Person(user.name, user.age)
}
println(person.introduce())
if (person is Worker) {
val result = person.work()
println(result)
Logger.log(LoginStatus.SUCCESS. "{user.name} 작업 시작")
} else {
Logger.log(LoginStatus.FAIL, "${user.name}은 Worker가 아닙니다.")
}
}
'Backend > Kotlin' 카테고리의 다른 글
| 테스트 코드, 대체 어떻게 쓰는걸까? 흐름을 따라가보자. (0) | 2025.05.28 |
|---|---|
| 자바와 코틀린 기초 비교 - 변수부터 Null 안정성까지 (0) | 2025.05.14 |