본문 바로가기
Kotlin

Kotlin Property , Custom Getter & Setter

by 봄석 2019. 10. 7.

Kotlin Property , Custom Getter & Setter

 

코틀린 프로퍼티에대하여 알아보기전에

먼저 프로퍼티와 필드에 대하여 알아보도록 하겠습니다.

 

Java의 프로퍼티와 필드

객체지향에서 객체는 고유한 속성(==특징)을 가지는 데, 그 속성을 칭하는 단어를 property 라고 합니다.

그리고 이 속성의 실체가 담기는 곳이 필드(멤버 변수)입니다.

public class Dog {

    private String name;
    private int old;

    public Dog(String name, int old) {
        this.name = name;
        this.old = old;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getOld() {
        return old;
    }

    public void setOld(int old) {
        this.old = old;
    }
}

 

setName, getName 메소드를 통해서 접근할 수 있는 value필드는 실제 이름과 상관없이 'Name'이라는 이름 으로 인식된다.

자바빈 기술에서 이런 메소드를 통해 관리되는 데이터를 프로퍼티(property) 라고 부르며

get, set 을 뗀 나머지 부분에서 첫문자를 소문자로 바꾼 이름을 프로퍼티 이름으로 취급합니다.

 

Dog라는 클래스는는 name과 old라는 property 가지고 있는 클래스이고,

java bean 정의에 의한 getter() 와 setter() 메소드로 실제 값(field)에 접근할 수있습니다.

 

정리 (자바에서 필드와 프로퍼티)

- 필드(field): 정의된 내용 실제의 값

- 속성(Property): getter와 setter를 메소드를 가지는 field

 

그렇다면 Kotlin 에서는 ?

코틀린에서는 필드 뿐만아니라 접근자 메소드도 자동으로 생성해줍니다.

즉 , 코틀린에서 클래스 내부 변수 선언은 모두 property 선언되는것입니다.


코틀린의 property는 var 와 val 로 선언할 수 있습니다.
property는 사용은 필드처럼 하지만, 호출하게 되면 함수처럼 호출됩니다.

ex)Kotlin의 내부 변수 선언

 

class People{
	val name:String
	var age:Int		  
}

위의 People  Class의 name은 읽기전용  property(with Getter),

age 는 읽기,쓰기(with Getter,Setter) 모두 가능한 property가 됩니다.

 

위의 People클래스처럼 프로퍼티만 존재하여 데이터만 저장하는 용도의 클래스를

값-객체(value-object)라 하며, data 키워드를 사용하여 data class로 선언하는것이 좋습니다.

 

 

ex)Kotlin property 사용하기 

people.name
people.age = 10

코틀린에서는 프로퍼티이름을 직접 사용하여도 자동으로 getter, setter호출로 변환하여줍니다.

자바에서 사용하였다면 getName(), setAge()를 호출했어야 되었을것입니다.

 

Kotlin Backing Field

kotlin에서는 위에서 이야기한 것 처럼 모두 프로퍼티로 선언되므로 field를 가질 수 없습니다.

하지만,  Kotlin에서는 'field'라는  식별자를 통해 접근할 수 있는 , automatic backing field를 제공합니다.

'field'는  property의 accessor에서만 접근가능합니다.

 

backing field의 생성조건

 

1) accessor중 1개라도 기본구현을 사용하는경우

2 )custom accessor에서 field 식별자를 참조하는 경우

var counter = 0 
	set(value){
    	if(value>=0) field =value
    }

아래같은 경우는 backing field를 사용하지 않습니다.

val isEmpty : Boolean 
	get() = this.size ==0

 

 

위에서 사용한 Peple이라는 클래스는 아래와 같게 볼 수 있습니다.

class People {
    val name: String = ""
        get() {
            return field
        }

    var age: Int = 0
        get() {
            return field
        }
        set(value) {
            field = value
        }
}

 

아래에서 더  자세히 보도록 하겠습니다.

 

Custom Getter & Setter Accessor( 커스텀 접근자)

프로퍼티를 accesor getter를 이용하여 단순히 값을 반환하는것이아니라 

특정한 연산을 수행한 수 결과를 반환해야 하는 것이라면

직접, 접근자 getter를 Custom하여 작성할 수 있습니다.

 

 

ex) custom getter accesor

val isSquare : Boolean 
	get() = height == width

위 처럼 호출될 때 마다 계산하여 수행결과를 반환합니다.

 

ex) custom setter accesor 에서 직접, 뒷받침필드(Backing Fields)에 접근하기 

class User (val name:String){
	var address : String = "unspecified"
    	set (value:String){
        	println("""
            	Address was changed for $name :
                $field -> $value """.trimIndent()
            )
            field=value
        }
}
fun main(args: Array<String>) {
    val user = User("bsjo")
    println(user.address)
    user.address= "Seoul Jung Rang - Gu, JungHwa Dong"
    println(user.address)
}
//result
unspecified
Address was changed for bsjo :
   unspecified -> Seoul Jung Rang - Gu, JungHwa Dong 
Seoul Jung Rang - Gu, JungHwa Dong

커스텀 접근자 setter를 지정할때 내부에서 field 키워드를 사용하지 않는다면

뒷받침 필드(Backing Fields)가 필요 없다는 의미이므로 알아서 생성되지 않습니다.

 

 

Property accessor에 가시성 설정하기

class People{
	val name:String
    
	var age:Int		
    	private set
}

var 변수의 setter accessor 를 위와같이 설정하게되면 

setter 를 private로 변경한것과 같으므로 

val처럼 사용할수 있습니다.

 

 

 

 

참고

https://thositeom.tistory.com/entry/%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0property-%EB%9E%80

https://www.slideshare.net/ssuser70d5d01/kotlin-9-properties-and-fields

https://kotlinlang.org/docs/reference/properties.html

'Kotlin' 카테고리의 다른 글

가변인자 알아보기 ( ... , vararg  (0) 2019.10.18
Sealed Class  (0) 2019.09.02
Fold, Reduce  (0) 2019.08.29
고차함수 (Higher-order-function) ,1급시민[객체,함수] (First-Class Citizen)  (0) 2019.08.29
Reflection  (0) 2019.06.08

댓글