Kotlin 기초 - 클래스와 프로퍼티

아래 내용은 Kotlin in Action 도서를 기반으로 작성하였습니다.

클래스와 프로퍼티

먼저 JavaBean 클래스인 Person을 정의해보면,

public class Person {
    private final String name;
    
    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

필드가 둘 이상으로 늘어날 경우 생성자의 본문에 대입문의 수가 늘어나며 또한 게터의 수도 늘어날 것이다. 이런 종류의 코드를 보일러플레이트 코드(Boilerplate code)라고 한다.

코틀린은 보일러플레이트 코드를 없애 위와 같은 필드 대입 로직을 훨씬 더 적은 코드로 작성할 수 있다.

class Person(val name: String)

단 한줄만으로 위의 자바 코드와 동일한 기능을 수행하는 클래스를 만들 수 있다.

이런 유형의 클래스(코드 없이 데이터만 저장하는 클래스)를 값 객체(Value object)라 하며 다양한 언어에서 이를 간결하게 기술할 수 있도록 구문을 제공한다.

위 코드를 보면 public 가시성 변경자가 사라졌다. 이걸로 코틀린의 기본 가시성은 public임을 알 수 있으며 이런 경우 변경자를 생략할 수 있다.

프로퍼티

자바에서는 필드(멤버 변수)와 접근자(Getter, Setter 등)을 하나로 묶어 프로퍼티(property)라고 부르며 이를 활용하는 프레임워크가 많다.

코틀린은 프로퍼티를 언어 기본 기능으로 제공하며 이는 자바의 필드와 접근자를 완전히 대체한다.

class PersonKt(
    //val : 읽기 전용 프로퍼티이며 코틀린은 private field와 public getter를 만들어낸다.
    val name: String,
    //var : 쓸 수 있는 프로퍼티이며 private field, public getter and setter를 만들어낸다.
    var isMarried: Boolean
)

코틀린에서 프로퍼티를 선언하는 방식은 프로퍼티와 관련 있는 접근자를 선언하는 것이다. 코틀린은 값을 저장하기 위한 비공개 필드, 값을 저장하는 세터, 값을 읽기 위한 게터로 이뤄진 간단한 디폴트 접근자 구현을 제공한다.

프로퍼티는 자바와 상호 호환되기 때문에 코틀린으로 정의한 클래스를 자바로 정의한 클래스와 동일하게 선언할 수 있다.

Person person = new Person("Bob", true);
System.out.println(person.getName());
System.out.println(person.isMarried());
Bob
True

코틀린의 name 프로퍼티는 자바에서 getName을 사용하여 이름을 볼 수 있다. 다만 is로 시작하는 프로퍼티의 게터는 get을 붙이지 않고 그대로 사용하며(isMarried()), 세터는 is를 set으로 바꾼다(setMarried()).

val person = Person("Bob", true)
println(person.name)
println(person.isMarried)
Bob
True

코틀린에서는 프로퍼티를 직접 사용한다. 동일한 로직이지만 코드는 좀 더 간결하다. 세터도 마찬가지로 프로퍼티에 직접 접근한다(person.isMarried = false).

자바 클래스를 코틀린처럼 사용할 수 있다. 코틀린에서는 게터를 val처럼, 게터와 세터 쌍을 var처럼 사용할 수 있다.

커스텀 접근자

직사각형 클래스인 Rectangle을 정의하면서 자신이 정사각형인지 알려주는 기능을 만들어보자. 직사각형인지 정사각형인지는 별도의 필드에 저장할 필요가 없다. 그때그때 검사하여 정사각형 여부를 알면 된다.

class Rectangle(val height: Int, val width: Int) {
    val isSquare: Boolean
        get() {
            return height == width
        }
}

여기서 알아둘 것은 isSquare 프로퍼티는 값을 저장하는 필드가 필요하지 않다. 이 프로퍼티는 게터만 제공한다. -> 프로퍼티에 접근할 때마다 게터가 프로퍼티 값을 매번 계산한다.

식이 본문일 경우에는 get() = height == width와 같이 사용할 수 있다.

커스텀 게터를 사용하는 프로퍼티도 앞서 본 프로퍼티와 동일하게 사용하면 된다.

val rectangle = Rectangle(41, 43)
println(rectangle.isSquare)
false

© 2021. All rights reserved.

Powered by Hydejack v9.1.6