[kotlin] 접근자 메서드

ByWindow·2023년 1월 31일
0

Kotlin

목록 보기
6/6
post-thumbnail

Properties


프로퍼티는 필드(Field)와 접근자 메서드(getter, setter)를 하나로 합친 것을 의미합니다.
접근자 메서드는 왜 사용하는 것일까요?
그것은 클래스를 사용하는 이유와 관련이 있습니다. 클래스를 사용하는 이유 중 하나가 OOP의 캡슐화를 위해서 입니다. 내부의 데이터를 캡슐화하고 캡슐화한 데이터를 다루는 코드를 클래스라는 하나의 주체 안에 가둬 둡니다. 즉, 필드를 통해 데이터를 저장하고, 접근자 메서드를 이용해서 데이터에 접근을 합니다.
코틀린에서는 클래스 내부의 프로퍼티를 val, var 키워드를 통해서 생성할 수 있습니다. 그렇다면 자바에서와 코틀린에서 프로퍼티를 생성할 때 차이점은 무엇일까요?

In Java

public class Person {
    private String name;

    // constructor
    public Person(String name){
        this.name = name;
    }

    // get set method
    public String getName() {
        return this.name;
    }

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

Person 클래스를 생성하고 name 필드를 선언하는 간단한 예제를 가져왔습니다. 자바에서는 name이라는 필드 하나에 getter와 setter, 그리고 생성자를 만들어 주어야 했기 때문에 코드양이 길어졌습니다. 필드가 여러개였다면 그만큼 더 번거로운 작업을 되었을 것입니다.

In Kotlin

class Person(var name: String)

하지만 코틀린에서는 위와 같이 한 줄의 코드로 프로퍼티를 생성할 수 있습니다. 코틀린은 변수를 만들어주기만 해도 getter와 setter를 내부적으로 컴파일 단계에서 자동으로 생성해주기 때문입니다.

클래스 선언 방식예시Getter 생성Setter 생성유형
키워드 없음class Person(name: String)XX생성자 매개변수
var 키워드class Person(var name: String)OO속성
val 키워드class Person(val name: String)OX속성

위 표와 같이 클래스를 생성할 때 매개변수 선언 방식으로 생성한다면 getter와 setter가 생성되지 않습니다. 따라서 해당 클래스의 프로퍼티에 접근 및 변경이 불가합니다.
또한 val로 선언된 필드의 경우, getter만 생성되지만, var로 선언된 필드의 경우, getter와 setter 둘 다 생성됩니다.

커스텀 접근자 메서드


이 부분을 공부하려고 앞에서 프로퍼티에 대해 살펴 보았습니다.
코틀린에서는 접근자 메서드(getter와 setter)를 커스텀하여 각각을 호출할 때 특정 연산을 할 수 있습니다.

Getter

get( ) =

  • 고정적인 값을 반환할 때 사용됩니다.

  • 안드로이드 개발에서 LiveData의 값을 가져올 때 사용되는 것을 볼 수 있습니다.

    @HiltViewModel
    class RegisterInfoViewModel @Inject constructor(
      ...
    ) : AndroidViewModel(application) {
    
      private val _pictureList = MutableLiveData<List<RegisterEstatePicture>>() // private으로 외부에서 접근 차단
      val pictureList: LiveData<List<RegisterEstatePicture>> // 외부에서 변경할 수 없음(참조만 가능)
        get() = _pictureList
      ...
    }
  • assignmnet(=)를 사용하여 필드에 값을 대입한 경우, 필드를 생성하는 동시에 필드의 값을 할당하는 것으로 필드와 getter가 둘 다 생성됩니다. 하지만 = 기호 없이 get을 사용하는 경우, 필드를 생성하지 않고 getter 함수를 통해 특정 객체만 반환합니다.

get( ) { }

  • 블럭 안의 로직을 수행하고 반환할 수 있습니다.

    class Person(name: String, age: Int){
        var name: String = name
        var age: Int = age
        	get() {
            	return age + 12 // age 필드 참조 시, 로직 수행 결과를 반환
        	}
    }

Setter

setter의 경우, set(value){ field = value }와 같이 사용됩니다. 필드에 접근하여 값을 value로 변경할 때 블럭 안의 로직이 수행됩니다.

private var state = State.BEFORE_RECORDING
    set(value) {
        field = value
        resetButton.isEnabled = (value == State.AFTER_RECORDING) || (value == State.ON_PLAYING)
        recordButton.updateIconWithState(value)
    }

setter를 활용한 코드입니다.
state의 값을 변경할 때, 변경하는 값에 따라서 UI를 변경해 줄 수 있으며 custom ui 내부의 메서드를 실행할 수 있습니다.

참고


profile
step by step...my devlog

0개의 댓글