코틀린 프로퍼티(property)란?

쓰리원·2022년 6월 14일
2

Kotlin Usage

목록 보기
1/4
post-thumbnail

1. Java의 필드

필드(field): 클래스의 속성값을 저장하기 위해 선언하는 변수들을 필드라고 합니다. 필드는 다른 말로 멤버변수나 전역변수라고 합니다.

필드는 클래스 안에서 선언 위치에 따라 3가지로 구분됩니다.

1. 지역 변수 (local variable)
2. 인스턴스 변수 (instance variable)
3. 클래스 변수 (class variable)

class class_name {
    static data_type variable_name; // 클래스 변수
    data_type variable_name; // 인스턴스 변수
    
    data_type method_name() {
        data_type variable_name; // 지역 변수
    }
}

1. 지역 변수(메서드나 생성자 내부 선언)

메서드 안에 선언된 변수를 의미합니다. 메서드가 호출될 때 생성되고 메서드가 종료될 때 삭제됩니다. stack 메모리에 저장되며 접근 지정자를 사용할 수 없습니다. 기본적으로 변수가 존재하는 블록에서만 사용할 수 있기 때문에 블록변수라고도 합니다. 반드시 사용하기 전에 초기화해야합니다.

(멤버 변수 : 인스턴스 변수, 클래스 변수 -> 선언 위치가 클래스 영역)

2. 인스턴스 변수

메서드 밖에서 선언된 변수 중 static 키워드를 사용하지 않고 선언된 변수입니다. 인스턴스(객체)가 생성될 때 생성되며 객체가 삭제될 때 삭제됩니다. 인스턴스 별로 다른 값을 가질 수 있으므로, 각각의 인스턴스마다 고유의 값을 가져야할 때는 인스턴스 변수로 선언합니다. heap 메모리에 저장되며 각 객체의 정보를 저장하는데 사용되어 멤버 변수라고도 합니다.

3. 클래스 변수

클래스 변수는 메서드 밖에서 선언된 변수 중 static 키워드를 사용하여 선언한 변수입니다. 프로그램이 실행될 때 생성되고 프로그램이 종료될 때 삭제됩니다. 단 한 번만 생성되고 객체 생성 없이 클래스명.변수명으로 접근할 수 있습니다. 메서드 영역에 할당되고 객체(인스턴스) 간에 공유되기 때문에 공유변수라고도 합니다.

2. Kotlin 프로퍼티와 필드

프로퍼티는 일반 변수처럼 보이지만 함수가 내장된 변수입니다. 접근자(Accessor)로 불리는 함수가 내장되어 있습니다. 코틀린에서는 필드 뿐만아니라 접근자(Accessor) 메서드도 자동으로 생성해줍니다. property는 사용은 필드처럼 하지만, 호출하게 되면 함수처럼 호출됩니다.

1. 프로퍼티 문법

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

initializer, getter, setter 는 optional 입니다. initializer 로부터 타입을 추론하는 것이 가능하다면 프로퍼티의 타입을 생략하는것이 가능합니다.

  • val : 읽기전용으로 사용
  • var : 읽기와 수정이 사용
  • propertyName: 프로퍼티명
  • PropertyType: 프로퍼티 타입 (타입 추론이 가능한 경우 생략 가능)
  • property_initializer: 프로퍼티 값 초기화 (초기화가 불필요한 경우 생략 가능)
  • getter / setter : 해당 프로퍼티에 대한 getter / setter를 정의 (생략할 경우 default getter, setter 적용) val 프로퍼티는 setter를 가질수없음

프로퍼티와 getter, setter는 접근제한자 (public, internal, protected, private) 적용이 가능합니다.

2. Backing Field

var counter = 0 // the initializer assigns the backing field directly
	get() = field
    set(value) {
        if (value >= 0)
            field = value
            // counter = value // ERROR StackOverflow: Using actual name 'counter' would make setter recursive
    }

프로퍼티는 get(), set() 함수를 가지고 있고 프로퍼티가 가진 값은 field에 저장되어 있습니다. get(),set()으로 데이터를 읽기 및 수정을 할 수 있습니다.

클래스 내의 프로퍼티의 getter, setter 역할을 하는 get(), set() 함수가 접근하는 field(필드)는 프로퍼티에 저장된 값 자체를 지칭하는 예약어 입니다. 이 필드라는 개념은 get(), set() 에서만 사용 가능합니다.

3. 프로퍼티 적용

예제1

public static final class Person {
    private int age;
    @NotNull
    private final String name;
 
    public final int getAge() {
        return this.age;
    }
 
    public final void setAge(int var1) {
        this.age = var1;
    }
 
    @NotNull
    public final String getName() {
        return this.name;
    }
 
    public Person(int age, @NotNull String name) {
        Intrinsics.checkNotNullParameter(name, "name");
        super();
        this.age = age;
        this.name = name;
    }
}

class Person(var age: Int, val name: String)

var로 선언한 age의 경우 getAge, setAge와 같이 getter, setter가 자동으로 생성되었습니다.

반면 val로 선언한 name의 경우 값 변경이 불가능하고 setter를 정의할 수 없기 때문에 당연하게 setter가 생성되지 않은 것을 확인할 수 있습니다.

보통 자바에서는 getter / setter는 필드값 반환, 세팅의 역할이 주였는데요. 코틀린에서의 getter / setter는 보다 다양하게 활용이 가능합니다.

예제2

public static final class Product {
  private int size;
 
  public final boolean isEmpty() {
      return this.size == 0;
  }
 
  public final int getSize() {
      return this.size;
  }
 
  public final void setSize(int var1) {
      this.size = var1;
  }
 
  public Product(int size) {
      this.size = size;
  }
}

class Product(var size: Int) {
    val isEmpty
        get() = this.size == 0
}

이런식으로 다른 필드를 활용한 계산된 (computed) 속성으로도 활용이 가능합니다. 또한 커스텀 setter를 지정하여 프로퍼티 값 설정 전 유효성 검사, 혹은 다른 동작도 지정할 수 있습니다.

아래 예시에서는 1~3 값만 설정가능한 grade 프로퍼티를 정의했습니다.
setter 로직 중 field가 실제 프로퍼티의 값인데 코틀린에서는 이를 Backing Fields라고 합니다.

class Person {
    var grade = 1
        set(value) {
            if (value in 1..3) {
                field = value
            } else {
                throw IllegalArgumentException("Grade 는 1 ~ 3 사이여야합니다.")
            }
        }
}

4. reference

https://kotlinlang.org/docs/properties.html
https://do-study.tistory.com/120
https://wooooooak.github.io/kotlin/2019/05/24/property/

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글