Getter und Setter in Kotlin

86

In Java kann ich zum Beispiel Getter selbst schreiben (von IDE generiert) oder Anmerkungen wie @Getter in lombok verwenden - was ziemlich einfach war.

Kotlin hat jedoch standardmäßig Getter und Setter . Aber ich kann nicht verstehen, wie man sie benutzt.

Ich möchte es schaffen, sagen wir - ähnlich wie Java:

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

Wie funktionieren Getter?

nutella_eater
quelle

Antworten:

142

Getter und Setter werden in Kotlin automatisch generiert. Wenn Sie schreiben:

val isEmpty: Boolean

Es entspricht dem folgenden Java-Code:

private final Boolean isEmpty;

public Boolean isEmpty() {
    return isEmpty;
}

In Ihrem Fall ist der Modifikator für den privaten Zugriff redundant - isEmpty ist standardmäßig privat und kann nur von einem Getter aufgerufen werden. Wenn Sie versuchen, die isEmpty-Eigenschaft Ihres Objekts abzurufen, rufen Sie die get-Methode in real auf. Zum besseren Verständnis der Getter / Setter in Kotlin: Die beiden folgenden Codebeispiele sind gleich:

var someProperty: String = "defaultValue"

und

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

Ich möchte auch darauf hinweisen, dass thisin einem Getter nicht Ihr Eigentum ist - es ist die Klasseninstanz. Wenn Sie in einem Getter oder Setter Zugriff auf den Feldwert erhalten möchten, können Sie das reservierte Wort fielddafür verwenden:

val isEmpty: Boolean
  get() = field

Wenn Sie nur eine get-Methode für den öffentlichen Zugriff haben möchten, können Sie diesen Code schreiben:

var isEmpty: Boolean
    private set 

Aufgrund des privaten Modifikators in der Nähe des Set-Accessors können Sie diesen Wert nur in Methoden innerhalb Ihres Objekts festlegen.

Cortwave
quelle
16
In your case the private access modifier is redundantWie? Der Standardmodifikator von Kotlin Docs ist öffentlich. kotlinlang.org/docs/reference/visibility-modifiers.html
@ Nichts ja es scheint wie öffentliches Feld, aber unter der Haube nennt man Getter-Methode
Cortwave
Das val isEmpty: Booleanwird nicht kompiliert, da isEmpty noch nicht initialisiert ist, oder? Ich fange gerade an, Kotlin zu lernen. Und was passiert mit get() = field?
Shubham A.
1
@Chiara val's haben keinen Setter
Chroder
@chroder ja du hast recht, ich muss falsch gelesen haben ... Kommentar gelöscht. Vielen Dank für den Hinweis
Chiara
30

Die Regeln für Sichtbarkeitsmodifikatoren von Eigenschaftszugriffsberechtigten lauten wie folgt:

  • Die bessere Sichtbarkeit von varund valEigenschaft sollte genau der Sichtbarkeit der Eigenschaft entsprechen. Sie können den Eigenschaftsmodifikator daher nur explizit duplizieren, er ist jedoch redundant:

    protected val x: Int
        protected get() = 0 // No need in `protected` here.
    
  • Die Sichtbarkeit des varObjekts sollte gleich oder weniger zulässig sein als die Sichtbarkeit des Objekts:

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

In Kotlin wird auf Eigenschaften immer über Getter und Setter zugegriffen, sodass es nicht erforderlich ist, eine Eigenschaft privatemit publicAccessoren wie in Java zu erstellen - das Hintergrundfeld (falls vorhanden) ist bereits privat. Daher werden Sichtbarkeitsmodifikatoren für Eigenschaftszugriffsmethoden nur verwendet, um die Sichtbarkeit des Setters weniger zulässig zu machen:

  • Für eine Eigenschaft mit Hintergrundfeld und Standard-Accessoren:

    var x = 0 // `public` by default
        private set
    
  • Für eine Eigenschaft ohne Hintergrundfeld:

    var x: Int // `public` by default
        get() = 0
        protected set(value: Int) { }
    
Hotkey
quelle
Kann man verschiedene Typen einstellen und bekommen? Gleichsetzen Sie x einige "Some String"und geben Sie die Länge 11der Zeichenfolge zurück.
Carel
@Carel, nein, dieser Anwendungsfall wird derzeit nicht unterstützt: Die Zugriffsmethoden einer Eigenschaft sollten genau mit dem Typ der Eigenschaft arbeiten. Die Verwendung eines anderen Typs wird durch die Verwendung einer separaten Backing-Eigenschaft
Hotkey
Verdammt, Kotlin ist Python so nahe, dass Sie denken, es würde nur funktionieren, wenn Sie daran erinnert werden, dass es getippt ist ... und sich die Kehle durchschneiden.
Carel
Vielen Dank für die Zugriffsmodifikatoren. Ich habe privateaus einer Variablen entfernt und sie wurde von einer anderen Klasse mit Getter zugänglich.
CoolMind
Ich erhalte die Meldung "Private Setter sind für offene Eigenschaften nicht zulässig", wenn die Kombination "var x // private set" verwendet wird. Gelöst durch Deklaration als "final var x"
Tom
14

1) Beispiel Standard setterund getterfür Eigenschaft firstName in Kotlin

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

}

Verwenden von

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

IF Ihre setteroder getterist genau die gleiche oben, können Sie es entfernen , weil es ist nicht notwendig

2) Beispiel für einen benutzerdefinierten Setter und Getter.

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")
            }
        }
}

Verwenden von

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

Mehr
Ich fange an, Kotlin von Java zu lernen, daher bin ich verwirrt fieldund propertyweil es in Java keine gibt property.
Nach einiger Suche sehe ich fieldund propertyin Kotlin sehe es aus wie C # ( Was ist der Unterschied zwischen einem Feld und einer Eigenschaft? )

Hier ist ein relevanter Beitrag, der über fieldund propertyin Java und Kotlin spricht .
Hat Java etwas Ähnliches wie C # -Eigenschaften?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

Korrigieren Sie mich, wenn ich falsch liege. Hoffe es hilft

Phan Van Linh
quelle
Danke, es hilft mir wirklich!
marcode_ely
8

Getter in Kotlin ist standardmäßig öffentlich, aber Sie können den Setter auf privat setzen und den Wert mithilfe einer Methode innerhalb einer Klasse festlegen. So was.

/**
* 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}")
}
Lalit Behera
quelle
5

Sie können dieses Tutorial für weitere Informationen sehen:

Noch ein Kotlin Tutorial für Android Entwickler

Eigenschaften

In der Kotlin-Welt können Klassen keine Felder haben, sondern nur Eigenschaften. Das Schlüsselwort var gibt an, dass die Eigenschaft im Gegensatz zu val veränderbar ist. Sehen wir uns ein Beispiel an:

class Contact(var number: String) {

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

}

Es gibt nicht viel Code, aber hinter den Kulissen passieren viele Dinge. Wir werden es Schritt für Schritt durchgehen. Zunächst haben wir einen öffentlichen Abschlusskontakt erstellt.

Dies ist die Hauptregel, der wir uns stellen müssen: Wenn nichts anderes angegeben ist, sind Klassen standardmäßig öffentlich und endgültig (dies gilt übrigens auch für Klassenmethoden). Wenn Sie von der Klasse erben möchten, markieren Sie sie mit dem Schlüsselwort open.

Pluto65
quelle
0

Hier ist ein praktisches Beispiel aus der Praxis für einen Kotlin Getter und Setter (Weitere Details finden Sie hier ):

// 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"

Ricky Padilla
quelle