클래스와 프로퍼티
2018, Jun 18
자바에서 데이터 저장을 위한 객체를 선언할때 보통 다음과 같은 모습을 가지게 된다.
//흔한 자바 클래스 구성
public class Person {
//필드
private final String name;
//필드를 초기화 하는 생성자
public Person(String name) {
this.name = name;
}
//accessor method
public String getName() {
return name;
}
}
- 자바에서는 데이터를 필드(field)에 저장하며, 멤버 필드의 가시성은 보통 비공개(private)이다.
- 데이터에 접근하기 위해 접근자 메소드(accessor method)-getter,setter가 필요하다.
- 자바에서
필드(field)
와접근자(accessor)
를 한데 묶어 프로퍼티(property)라고 부르며,
프로퍼티라는 개념을 활용하는 프레임워크가 많다. - 필드가 둘 이상 늘어나면 그에 따른 대입 로직도 추가로 생기고, 접근 메소드도 추가 되어야 하며, 자바에서는 이와 같은 코드가 반복적으로 들어가는 경우가 많다.
코틀린의 프로퍼티
- 코틀린 프로퍼티는 자바의 필드와 접근자 메소드를 완전히 대신하기 때문에, 그런 필드 대입 로직을 훨씬 더 적은 코드로 작성할 수 있다.
- 코틀린은 값을 저장하기 위한 비공개 필드(backing field)와 getter, setter로 이루어진 디폴트 접근자 구현을 제공한다.
class Person {
var name: String = ""
var isMarried: Boolean = false
}
>>> val p = Person()
>>> p.name = "charlse" //accessors are called
게터와 세터(Getters and Setters)
property 선언의 full syntax는 아래와 같다.
var <프로퍼티명>[: <프로퍼티타입>] [= <프로퍼티 초기화>]
[<게터>]
[<세터>]
프라퍼티 초기화(initializer)(초기값), getter와 setter, 프로퍼티 타입은 선택사항이다.
properties의 타입은 initializer로 부터 가능한 경우 추론된다.
클래스의 프로퍼티를 선언할때는 val
이나 var
를 사용한다.
val로 선언한 프로퍼티는 읽기 전용이므로 setter가 존재하지 않는다. var는 변경 가능하므로 getter, setter둘다 적용된다.
//추론을 통해 Int타입으로 정의됨
//기본으로 getter, setter를 가진다.
var initialized = 1
//오류 발생
//default getter setter를 사용한 경우로, 명시적인 초기화가 필요하다.
var allByDefault: Int?
//추론을 통해 Int타입으로 정의됨
//default getter를 가짐
val inferredType = 1
//오류 발생
//명시적인 초기화가 필요하다.
val simple: Int?
커스텀 접근자(Custom accessors)
getter나 setter는 아래와 같이 custom이 가능하다.
관례상, setter의 파라미터명은 value
로 지정되지만, 원한다면 변경이 가능하다.
- SampleClass의 프로퍼티 isEmpty의 경우 별도의 초기화(property_initializer)가 필요 없다.
-
get()의 수정으로 isEmpty를 참조할때 바로바로 값을 알수 있기 때문이다. (이것은 객체가 생성하는 시기에 초기화 단계에서 이루어 지는 것이 아니라 참조 할때 마다 getter의 본문을 실행하게 된다.)
- 코틀린 1.1 부터는 컴파일러가 추론할 수 있는 상황에서는 프로퍼티 타입을 생략 할 수 있다.
-
accessor의 블록 또한 사용하여도 되지만, 위와 같이 생략도 가능하다.
-
accessor에 가시성 변경이 필요하거나, 어노테이션이 필요한 경우 기본 accessor의 수정 없이 body없는 accessor를 통해 정의 가능하다.
Backing Field(지원 필드)
- 코틀린에서는 자바에서와 같은 필드가 존재하지 않고, 프로퍼티의 값을 저장하기위한 비공개 필드를 제공하다.
- 이것을 프로퍼티를 지원하는 필드(backing field)라고 한다.
- backing field는 accessor안에서
field
식별자를 이용해 사용한다.
- 코틀린 컴파일러는 디폴트로 접근자 구현을 사용하건, 커스텀 getter나 setter를 사용하건 backing field를 생성해 준다.
하지만 filed를 사용하지 않는 커스텀 접근자 구현을 정의한다면, backing 필드는 존재 하지 않는다.