최근에 enum class를 사용하면서 이런 코드를 작성했습니다.
enum class SortField(val label: String) {
SlipNumber("전표 번호순"),
RegisteredDate("완료 일시 순")
}
그런데 사용하다가 문득,
“생성자에서 label을 정의해준 것뿐인데, 왜 field.label처럼 바로 접근해서 사용할 수 있을까?”
하는 의문이 들었습니다.
이게 단순히 val이라 그런 건지, 아니면 코틀린이 프로퍼티를 특별하게 다루는 건지 궁금해서
조금 더 자세히 공부해본 내용을 정리해두기로 했습니다.
1. 프로퍼티란 무엇일까?
간단히 말해서,
프로퍼티(Property)는 “객체(Object)가 가지고 있는 속성(데이터)”을 의미합니다.
예를 들어 사람을 표현하는 Person 클래스를 만들어보겠습니다.
class Person(val name: String, var age: Int)
여기서 name은 사람의 이름 age는 사람의 나이입니다.
이 두 가지는 모두 Person 객체가 가지고 있는 정보, 즉 프로퍼티(property) 입니다.
2. 프로퍼티 사용 예시
val person = Person("민수", 25)
println(person.name) // "민수"
println(person.age) // 25
person은 Person 클래스의 객체이고
name과 age는 그 객체가 가지고 있는 프로퍼티입니다.
즉, person.name은 “민수”, person.age는 “25”라는 값을 가집니다.
프로퍼티는 이렇게 객체의 상태(state) 를 표현하는 역할을 합니다.
3. 코틀린의 프로퍼티가 특별한 이유
사실 “프로퍼티(property)”라는 개념은 코틀린에만 있는 것은 아닙니다.
하지만 코틀린은 이 개념을 언어 차원에서 깔끔하게 통합했습니다.
다른 언어에서는 일반적으로 필드(field) 와 getter/setter를 따로 작성해야 합니다.
예를 들어 자바에서는 다음과 같이 길게 써야 합니다.
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
반면 코틀린에서는 아래 코드 한 줄이면 끝입니다.
class Person(var name: String)
이 한 줄은 내부적으로 다음과 같은 의미를 가집니다.
class Person {
private var _name: String = ""
var name: String
get() = _name
set(value) {
_name = value
}
}
즉,
- name 프로퍼티를 정의하면 자동으로 백필드(backing field) 와 getter/setter가 생성됩니다.
- 개발자는 프로퍼티 이름만 정의하면 마치 변수를 다루듯이 person.name 형태로 접근할 수 있습니다.
이 덕분에 코틀린에서는 필드와 접근자를 구분할 필요 없이 하나의 문법으로 프로퍼티를 선언하고 사용할 수 있습니다.
4. enum class에서도 프로퍼티를 가질 수 있다
이제 처음 이야기로 돌아와서
왜 enum class에서 label을 생성자 인자로 정의했을 뿐인데
field.label로 접근할 수 있었을까요?
그 이유도 바로 코틀린의 프로퍼티 구조 덕분입니다.
enum class도 일반 클래스처럼 프로퍼티를 가질 수 있는 클래스의 한 형태이기 때문입니다.
enum class SortField(val label: String) {
SlipNumber("전표 번호순"),
RegisteredDate("완료 일시 순")
}
여기서 val label: String은 각 enum 객체가 가지고 있는 읽기 전용 프로퍼티입니다.
그래서 아래 코드가 가능한 것입니다.
val field = SortField.RegisteredDate
println(field.label) // "완료 일시 순"
즉,
- SortField.RegisteredDate는 SortField 클래스의 객체이고
- label은 그 객체가 가진 프로퍼티입니다.
따라서 field.label은 객체의 프로퍼티 접근 문법으로 자연스럽게 동작합니다.
5. UI 코드에서 프로퍼티를 사용하는 예시
Jetpack Compose로 화면을 구성할 때도 이런 프로퍼티를 그대로 활용할 수 있습니다.
@Composable
fun SortFieldLabel(sortField: SortField) {
Text(sortField.label)
}
sortField.label은 String 타입의 프로퍼티이므로 Text()에 그대로 전달할 수 있습니다.
결과적으로 Text("완료 일시 순")처럼 화면에 표시됩니다.
6. 프로퍼티와 변수의 차이
| 구분 | 변수(var/val) | 프로퍼티 |
| 정의 위치 | 함수 내부 | 클래스나 객체 내부 |
| 역할 | 일시적인 데이터 저장 | 객체의 속성(상태) 표현 |
| 예시 | val x = 10 | class User(val name: String) |
7. 정리
- 프로퍼티(Property)는 객체가 가진 데이터(속성) 입니다.
- 코틀린은 필드와 접근자(getter/setter) 를 통합해 프로퍼티를 간결하게 표현합니다.
- enum class도 프로퍼티를 가질 수 있습니다.
- 생성자에서 정의한 프로퍼티는 자동으로 객체의 속성으로 관리됩니다.
- object.propertyName 형태로 접근할 수 있습니다.
마무리하며
단순히 enum class의 생성자 인자로 label을 넣었을 뿐인데
왜 바로 field.label처럼 사용할 수 있는지 궁금했는데
공부해보니 코틀린의 프로퍼티 구조 자체가 그 이유였습니다.
코틀린은 프로퍼티를 “필드 + 접근자”로 통합해 처리하기 때문에
개발자는 별도의 코드를 작성하지 않아도 객체의 속성을 자연스럽게 다룰 수 있습니다.
이 부분을 이해하고 나니, 코틀린이 왜 “표현이 간결한 언어”라고 불리는지 조금은 실감이 났습니다.
'Android > Kotlin' 카테고리의 다른 글
| [Android/Kotlin] Kotlin 컬렉션 확장 함수 정리: associateBy 사용법 (0) | 2025.03.27 |
|---|---|
| [Android/Kotlin] lateinit 이해하기: nullable과의 차이와 지연 초기화 이해하기 (0) | 2025.02.25 |
| [Android/Kotlin] mutableMapOf vs hashMapOf 차이점 및 성능 비교 (0) | 2025.02.06 |
| [Android/Kotlin] fold 사용법과 예제 (1) | 2025.02.05 |
| [Android/Kotlin] 코틀린의 mutableMapOf()는 왜 LinkedHashMap을 사용할까? (0) | 2025.02.04 |