Kotlin의 게터 및 세터


89

예를 들어 Java에서는 직접 getter를 작성하거나 (IDE에서 생성) lombok에서 @Getter와 같은 주석을 사용할 수 있습니다. 매우 간단합니다.

그러나 Kotlin에는 기본적으로 getter 및 setter가 있습니다. 그러나 나는 그것들을 사용하는 방법을 이해할 수 없습니다.

나는 그것을 만들고 싶다. 자바와 비슷하다.

private val isEmpty: String
        get() = this.toString() //making this thing public rises an error: Getter visibility must be the same as property visibility.

그렇다면 게터는 어떻게 작동합니까?

답변:


148

Getter 및 Setter는 Kotlin에서 자동 생성됩니다. 당신이 쓰는 경우 :

val isEmpty: Boolean

다음 Java 코드와 동일합니다.

private final Boolean isEmpty;

public Boolean isEmpty() {
    return isEmpty;
}

귀하의 경우 개인 액세스 수정자는 중복입니다-isEmpty는 기본적으로 개인이며 getter에서만 액세스 할 수 있습니다. 개체의 isEmpty 속성을 얻으려고 할 때 실제로 get 메서드를 호출합니다. Kotlin의 게터 / 세터에 대한 더 많은 이해를 위해 아래 두 코드 샘플이 동일합니다.

var someProperty: String = "defaultValue"

var someProperty: String = "defaultValue"
    get() = field
    set(value) { field = value }

또한 나는 thisgetter에서 당신의 재산이 아니라 클래스 인스턴스 라는 것을 지적하고 싶습니다 . getter 또는 setter에서 필드 값에 액세스하려면 예약어를 사용할 수 있습니다 field.

val isEmpty: Boolean
  get() = field

퍼블릭 액세스에서만 get 메소드를 사용하려면 다음 코드를 작성할 수 있습니다.

var isEmpty: Boolean
    private set 

set 접근 자 근처의 private 한정자로 인해이 값은 개체 내부의 메서드에서만 설정할 수 있습니다.


17
In your case the private access modifier is redundant어떻게? Kotlin doc의 기본 수정자는 공개입니다. kotlinlang.org/docs/reference/visibility-modifiers.html

@Nothing yes 그것은 공개 필드처럼 보이지만 후드에서 당신은 getter 메소드를 호출합니다
Cortwave

val isEmpty: BooleanIsEmpty 함수가 아직 초기화되지 않기 때문에, 권리를 컴파일되지 않습니다? Kotlin을 배우기 시작했습니다. 또한 무슨 일이 일어나고 get() = field있습니까?
Shubham A.

1
@Chiara val's have no setter
chroder

@chroder 네 맞아요, 제가 잘못 읽었 나봐요 ... 댓글이 삭제되었습니다. 그것을 지적 주셔서 감사합니다
키아라

30

속성 접근 자 가시성 수정 자 에 대한 규칙은 다음과 같습니다.

  • varval속성 의 Getter 가시성은 속성의 가시성 과 정확히 동일 해야 하므로 속성 수정자를 명시 적으로 복제 만 할 수 있지만 중복됩니다.

    protected val x: Int
        protected get() = 0 // No need in `protected` here.
    
  • var속성의 Setter 가시성은 속성 가시성과 동일하거나 덜 관대 해야합니다 .

    protected var x: Int
        get() = 0
        private set(x: Int) { } // Only `private` and `protected` are allowed.
    

Kotlin에서 속성은 항상 getter 및 setter를 통해 액세스되므로 Java와 같은 접근자를 사용하여 속성 private을 만들 필요가 없습니다. 지원 필드 (있는 경우) 는 이미 비공개입니다. 따라서 속성 접근 자의 가시성 수정자는 setter 가시성을 덜 허용 적으로 만드는 데만 사용됩니다.public

  • 지원 필드 및 기본 접근자가있는 속성의 경우 :

    var x = 0 // `public` by default
        private set
    
  • 지원 필드가없는 속성의 경우 :

    var x: Int // `public` by default
        get() = 0
        protected set(value: Int) { }
    

한 세트로 다른 유형을 얻을 수 있습니까? x some "Some String"과 같게 설정 하고 반환 11하면 문자열 의 길이, ?
Carel

@Carel, 아니요, 현재이 사용 사례는 지원되지 않습니다. 속성의 접근자는 속성의 유형과 정확하게 작동해야합니다. 다른 유형을 사용하는 것은 별도의 백업 속성
hotkey

젠장, Kotlin은 Python과 매우 가까워서 입력 한 것을 상기시키고 목을 자르면 작동 할 것이라고 생각합니다.
Carel

액세스 수정 자 주셔서 감사합니다. private변수에서 제거 하고 getter를 사용하여 다른 클래스에서 액세스 할 수있게되었습니다.
CoolMind

"var x // private set"조합을 사용할 때 "Private setter는 열린 속성에 대해 허용되지 않습니다"라는 메시지가 나타납니다. "final var x"로 선언하여 해결됨
Tom

15

1) 예 기본 settergetter대한 재산 firstName 코 틀린에

class Person {
    var firstName: String = ""
            get() = field       // field here ~ `this.firstName` in Java or normally `_firstName` is C#
            set(value) {
                field = value
            }

}

사용

val p = Person()
p.firstName = "A"  // access setter
println(p.firstName) // access getter (output:A)

경우 귀하 setter또는 getter이다 정확히 같은 이상이 있기 때문에, 당신은 그것을 제거 할 수 있습니다 불필요

2) 예제 사용자 지정 세터 및 게터.

const val PREFIX = "[ABC]"

class Person {

    // set: if value set to first name have length < 1 => throw error else add prefix "ABC" to the name
    // get: if name is not empty -> trim for remove whitespace and add '.' else return default name
    var lastName: String = ""
        get() {
            if (!field.isEmpty()) {
                return field.trim() + "."
            }
            return field
        }
        set(value) {
            if (value.length > 1) {
                field = PREFIX + value
            } else {
                throw IllegalArgumentException("Last name too short")
            }
        }
}

사용

val p = Person()
p.lastName = "DE         " // input with many white space
println(p.lastName)  // output:[ABC]DE.
p.lastName = "D" // IllegalArgumentException since name length < 1


난에 대해 혼동하고 그래서 자바에서 코 틀린 내용을 보려면 시작 field하고 property자바에 더 있기 때문에 property.
일부 검색 후, 나는 볼 fieldpropertyC #을 같은 코 틀린 모양에 ( 필드와 속성의 차이점은 무엇입니까? )

여기에 대해 이야기 몇 가지 관련 게시물 fieldpropertyJava 및 코 틀린에.
Java에는 C # 속성과 비슷한 것이 있습니까?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

내가 틀렸다면 정정하십시오. 도움이 되었기를 바랍니다.


감사합니다. 정말 도움이됩니다!
marcode_ely

8

kotlin의 Getter는 기본적으로 public이지만 setter를 private으로 설정하고 클래스 내에서 하나의 메서드를 사용하여 값을 설정할 수 있습니다. 이렇게.

/**
* Created by leo on 17/06/17.*/

package foo
class Person() {
var name: String = "defaultValue"
               private set

fun foo(bar: String) {
    name = bar // name can be set here
       }
}

fun main(args: Array<String>) {
  var p = Person()
  println("Name of the person is ${p.name}")
  p.foo("Jhon Doe")
  println("Name of the person is ${p.name}")
}

5

자세한 내용은이 자습서를 참조하십시오.

Android 개발자를위한 또 다른 Kotlin 자습서

속성

Kotlin 세계에서 클래스는 필드를 가질 수없고 속성 만 가질 수 있습니다. var 키워드는 val과 달리 속성이 변경 가능함을 알려줍니다. 예를 보겠습니다.

class Contact(var number: String) {

   var firstName: String? = null
   var lastName: String? = null
   private val hasPrefix : Boolean
       get() = number.startsWith("+")

}

코드가 많지는 않지만 뒤에서 많은 일이 일어나고 있습니다. 우리는 그것을 단계적으로 살펴볼 것입니다. 먼저 공개 최종 클래스 Contact를 만들었습니다.

이것이 우리가 직면해야 할 기본 규칙입니다. 달리 지정하지 않으면 클래스는 기본적으로 공개되고 최종적으로 사용됩니다 (그런데 클래스 메서드도 마찬가지입니다). 클래스에서 상속하려면 open 키워드로 표시하십시오.


0

다음은 Kotlin getter 및 setter의 실제 실제 사례입니다 (자세한 내용은 여기 참조 ).

// Custom Getter
val friendlyDescription get(): String {
    val isNeighborhood = district != null
    var description = if (isNeighborhood) "Neighborhood" else "City"
    description += " in"
    if (isNeighborhood) {
        description += " $city,"
    }
    province?.let {
        if (it.isNotEmpty()) {
            description += " $it,"
        }
    }
    description += " $country"
    return description
}

print(myLocation.friendlyDescription) // "Neighborhood in Denver, Colorado, United States"


// Custom Setter
enum class SearchResultType {
    HISTORY, SAVED, BASIC
}

private lateinit var resultTypeString: String

var resultType: SearchResultType
    get() {
        return enumValueOf(resultTypeString)
    }
    set(value) {
        resultTypeString = value.toString()
    }

result.resultType = SearchResultType.HISTORY
print(result.resultTypeString) // "HISTORY"

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.