목차
개요
Kotlin의 클래스 역시 Java와 마찬가지로 각 필드에 대한 getter와 setter가 존재한다. 이번 포스트에서는 Kotlin 클래스의 기본적인 getter와 setter 및 Kotlin 클래스의 커스텀 getter와 setter에 대해 정리한다.
Kotlin 클래스의 기본 getter와 setter
Kotlin에서 클래스를 작성하는 방법은 Kotlin 기본 문법 6 : 클래스와 접근 지정자 포스트에서 이미 다룬바가 있다. Kotlin 클래스의 필드는 기본적으로 Java와 달리 별도의 getter, setter 메소드로 접근하지 않는다. 대신 Kotlin에서는 클래스의 생성자를 작성하면 필드의 종류(val
, var
)에 따라 자동으로 getter와 setter를 생성해주고, 일반적으로 필드에 접근하듯이 객체명.필드명을 사용하면 자동으로 getter와 setter를 호출하게 되므로 별도의 getter와 setter를 작성할 필요가 없다.
위 사진을 보면 val
로 설정한 name은 getter만 생성되었고, var
로 작성한 age는 getter와 setter가 모두 생성된 것을 볼 수 있다.
커스텀 getter
커스텀 getter는 기본 getter 외에 추가적인 getter가 필요할 때 사용한다. 예를 들어 직사각형을 나타내는 Rectangle 클래스가 있다.
class Rectangle(var width: Int, var height: Int)
이 Rectangle 클래스에서 직사각형의 넓이나 대각선의 길이를 구하고 싶다면 클래스 내부에 넓이를 나타내는 필드를 새로 작성하면 된다고 생각할 수 있다.
class Rectangle(var width: Int, var height: Int) {
val area = width * height
}
하지만 이 방법은 직접 사용해보면 아래와 같은 문제가 있다.
fun main() {
val rectangle = Rectangle(3, 5)
println(rectangle.area)
rectangle.width = 4
println(rectangle.area)
}
/*
15
15
*/
이러한 문제가 발생하는 이유는 area는 생성자로 객체가 초기화될 때 함께 초기화되는 필드이기 때문에 그 이후에 직사각형의 가로나 세로가 바뀌더라도 객체가 초기화될 당시에 넓이가 초기화된 상태로 저장되어 변하지 않기 때문이다. 이 문제를 해결하기 위해선 커스텀 getter를 사용할 수 있다.
커스텀 getter를 작성하는 방법은 어렵지 않다. 변수를 작성할 때와 마찬가지로 val
을 사용하여 변수를 선언하고 변수명 뒤에 get()
을 선언하여 메소드를 작성하는 것과 비슷하게 작성한다. 반환값 타입은 메소드와 마찬가지로 등호(=)를 사용해 한줄로 작성하였을 때는 생략할 수 있지만, 코드 블럭을 생성하여 return
을 사용할 경우에는 변수명 뒤에 타입을 명시해줘야 한다. 다음은 위의 Rectangle 클래스의 넓이를 커스텀 getter로 변경한 코드이다.
class Rectangle(var width: Int, var height: Int) {
val area get() = width * height
/* 아래와 같이 작성해도 된다.
val area: Int
get() {
return width * height
}
*/
}
커스텀 getter를 사용하면 넓이를 호출할 때마다 현재 객체의 가로와 세로 길이를 토대로 계산하여 반환하게 된다.
fun main() {
val rectangle = Rectangle(3, 5)
println(rectangle.area)
rectangle.width = 4
println(rectangle.area)
}
/*
15
20
*/
커스텀 getter 역시 Java코드로 디컴파일해보면 별도의 getter로 변환되어 있는 것을 볼 수 있다.
커스텀 setter
커스텀 setter는 기본적인 setter에 추가적인 기능을 부여하고자 할 때 사용한다. 커스텀 setter를 작성할 때 주의할 점은 커스텀 setter를 작성할 필드는 클래스의 기본 생성자에 필드를 작성하는 것이 아니라 클래스 내부에 필드를 작성하여 생성자의 파라미터를 받아와야 한다는 점이다. 필드 선언 아래에 set(value)
를 선언하고 커스텀 getter와 마찬가지로 메소드를 작성하듯이 작성한다. 예를 들어 Person 클래스에서 이름을 변경할 때 반드시 대문자로 설정되는 setter를 작성한다.
class Person(name: String, var age: Int) {
var name = name
set(value) {
field = value.uppercase()
}
}
예시의 Person 클래스는 생성자에서 name 필드가 선언된 것이 아니라 생성자는 단순히 파라미터로 name을 받아 필드의 name에 할당하는 것을 볼 수 있다. 그리고 바로 아래에 커스텀 setter가 작성되는데 field
라는 것이 작성된 것을 볼 수 있다. 이 field
에 마우스를 올려보면 바로 위에 선언되어 있는 필드라는 것을 알 수 있다.
이제 Person 클래스는 객체를 새로 생성할 때는 name 필드에 그대로 들어가게 되지만 name 필드를 변경하게 되면 모두 대문자로 변경된다.
fun main() {
val person = Person("jack", 20)
println(person.name)
person.name = "chris"
println(person.name)
}
/*
jack
CHRIS
*/
커스텀 setter 역시 Java 코드로 디컴파일해보면 setter로 변환되는 것을 볼 수 있다.
마무리
이번 포스트에서는 Kotlin 클래스의 커스텀 getter와 커스텀 setter에 대해 정리해보았다. 커스텀 getter는 객체에서 별도의 계산이 필요한 값을 얻어올 때 메소드 대신 사용할 수 있고, 커스텀 setter는 필드의 값을 변경할 때 추가적인 연산을 수행하게 해준다.
다음 포스트에서는 Kotlin의 스코프 함수에 대해 정리할 예정이다.
댓글 피드백은 언제나 환영합니다.
'Programming Language > Kotlin & Java' 카테고리의 다른 글
[Kotlin] 기본 매개변수(Default parameter)와 명명된 인자(Named Arguments) (0) | 2022.12.27 |
---|---|
Kotlin 기본 문법 11 : 스코프 함수(let, run, also, apply, with) (0) | 2022.12.26 |
Kotlin 기본 문법 9 : Kotlin의 다양한 클래스(Data Class, Enum Class, Sealed Class) (0) | 2022.12.16 |
Kotlin 기본 문법 8 : 정적 변수와 정적 메소드(feat. companion object) (0) | 2022.12.14 |
Kotlin 기본 문법 7 : 추상 클래스/인터페이스와 클래스의 상속 (0) | 2022.12.13 |
댓글