कोटलिन में गेटर्स एंड सेटर्स


86

जावा में, उदाहरण के लिए, मैं अपने दम पर गेटर्स लिख सकता हूं (आईडीई द्वारा उत्पन्न) या लूमॉक में @ गीटर जैसे एनोटेशन का उपयोग कर सकता हूं - जो बहुत सरल था।

कोटलिन में हालांकि डिफ़ॉल्ट रूप से गेटर्स और सेटर हैं । लेकिन मैं समझ नहीं पा रहा हूं कि उनका इस्तेमाल कैसे किया जाए।

मैं इसे बनाना चाहता हूं, जो कहता है - जावा के समान:

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

तो गेटर्स कैसे काम करते हैं?

जवाबों:


142

कोटलिन में गेटर्स और सेटर स्वतः उत्पन्न होते हैं। यदि आप लिखते हैं:

val isEmpty: Boolean

यह निम्न जावा कोड के बराबर है:

private final Boolean isEmpty;

public Boolean isEmpty() {
    return isEmpty;
}

आपके मामले में निजी एक्सेस संशोधक निरर्थक है - isEmpty डिफ़ॉल्ट रूप से निजी है और इसे केवल एक गेटटर द्वारा एक्सेस किया जा सकता है। जब आप अपनी वस्तु को प्राप्त करने की कोशिश करते हैं, तो आप वास्तविक तरीके से संपत्ति प्राप्त करते हैं। कोटलिन में गेटर्स / सेटर्स की अधिक समझ के लिए: नीचे दिए गए दो कोड नमूने बराबर हैं:

var someProperty: String = "defaultValue"

तथा

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

इसके अलावा, मैं यह thisबताना चाहता हूं कि एक गेटटर में आपकी संपत्ति नहीं है - यह वर्ग का उदाहरण है। यदि आप एक गेट्टर या सेटर में क्षेत्र के मूल्य तक पहुंच प्राप्त करना चाहते हैं, तो आप fieldइसके लिए आरक्षित शब्द का उपयोग कर सकते हैं :

val isEmpty: Boolean
  get() = field

यदि आप केवल सार्वजनिक पहुँच में एक विधि प्राप्त करना चाहते हैं - आप इस कोड को लिख सकते हैं:

var isEmpty: Boolean
    private set 

सेट एक्सेसर के पास निजी संशोधक के कारण आप इस मान को केवल अपने ऑब्जेक्ट के अंदर के तरीकों में सेट कर सकते हैं।


16
In your case the private access modifier is redundantकैसे? कोटलिन डॉक्टर का कहना है कि डिफ़ॉल्ट संशोधक सार्वजनिक है। kotlinlang.org/docs/reference/visibility-modifiers.html

@ सुखद यह सार्वजनिक क्षेत्र की तरह लगता है, लेकिन हुड के तहत आप
गेट्टर

val isEmpty: Booleanसही संकलन नहीं होगा के रूप में isEmpty अभी तक प्रारंभ नहीं किया गया है,? बस कोटलिन सीखना शुरू कर रहा है। इसके अलावा, क्या हो रहा है get() = field?
शुभम ए।

1
@ चियारा valका कोई सेटर नहीं है
चेरेडर

@chroder हाँ आप सही हैं, मैंने गलत पढ़ा होगा ... टिप्पणी हटा दी गई। इसे इंगित करने के लिए धन्यवाद
चियारा

30

संपत्ति एक्सेसर्स दृश्यता संशोधक के बारे में नियम निम्नलिखित हैं:

  • प्रॉपर्टी की दृश्यता varऔर valप्रापर्टी की दृश्यता बिल्कुल समान होनी चाहिए , इस प्रकार आप केवल प्रॉपर्टी संशोधक की स्पष्ट रूप से नकल कर सकते हैं, लेकिन यह बेमानी है:

    protected val x: Int
        protected get() = 0 // No need in `protected` here.
    
  • के सेटर दृश्यता varसंपत्ति होना चाहिए एक ही या उससे कम अनुमोदक संपत्ति दृश्यता की तुलना में:

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

कोटलिन में संपत्तियों को हमेशा गेट्टर और सेटर के माध्यम से एक्सेस किया जाता है, इस प्रकार जावा में एक्सेसर्स के privateसाथ संपत्ति बनाने की कोई आवश्यकता नहीं है public- इसका बैकिंग फ़ील्ड (यदि मौजूद है) पहले से ही निजी है। इसलिए, प्रॉपर्टी ऐक्सेसर्स पर दृश्यता संशोधक का उपयोग केवल सेटर दृश्यता को कम अनुमति देने के लिए किया जाता है:

  • बैकिंग फ़ील्ड और डिफ़ॉल्ट एक्सेसर्स वाली संपत्ति के लिए:

    var x = 0 // `public` by default
        private set
    
  • फ़ील्ड के बिना किसी संपत्ति के लिए:

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

क्या कोई सेट कर सकता है और विभिन्न प्रकार प्राप्त कर सकता है? x कुछ के बराबर सेट करना "Some String"और लौटना 11स्ट्रिंग की लंबाई कहिए ?
Carel

@ कैरेल, नहीं, अब तक, इस उपयोग के मामले का समर्थन नहीं किया गया है: संपत्ति के एक्सेसर्स को संपत्ति के प्रकार के साथ काम करना चाहिए। एक अलग प्रकार का उपयोग करना एक का उपयोग करके कवर किया जाता है अलग समर्थन संपत्ति
हॉटकी

डार, कोटलिन अजगर के बहुत करीब है कि आपको लगता है कि यह सिर्फ तब काम करेगा जब आपको याद दिलाया जाएगा कि यह टाइप किया गया है ... और अपना गला काट लें।
केयरिंग

पहुँच संशोधक के लिए धन्यवाद। मैंने privateएक चर से हटा दिया , और यह गेट्टर के साथ दूसरे वर्ग से सुलभ हो गया।
CoolMind

मुझे "var x // निजी सेट" संयोजन का उपयोग करते समय "निजी बसने वालों को खुली संपत्तियों की अनुमति नहीं है"। "अंतिम वार x" घोषित करके हल किया गया
टॉम

14

1) उदाहरण के लिए setterऔर कोटलिन में संपत्ति केgetter लिए 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
कुछ खोज के बाद, मैं देखता हूं fieldऔर propertyकोटलिन सी # की तरह दिखता है ( एक क्षेत्र और एक संपत्ति के बीच अंतर क्या है? )

यहाँ कुछ प्रासंगिक जिस पद के बारे में बात है fieldऔर propertyजावा और Kotlin में।
क्या जावा में C # प्रॉपर्टीज के समान कुछ है?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

अगर मैं ग़लत हूं तो मेरी गलती सुझाएं। आशा है कि यह मदद करेगा


धन्यवाद, यह वास्तव में मेरी मदद करता है!
Marcode_ely

8

कोटलिन में गेटटर डिफ़ॉल्ट रूप से सार्वजनिक होता है, लेकिन आप सेटर को निजी में सेट कर सकते हैं और एक कक्षा के अंदर एक विधि का उपयोग करके मूल्य निर्धारित कर सकते हैं। इस प्रकार सं।

/**
* 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 डेवलपर्स के लिए एक और कोटलिन ट्यूटोरियल

गुण

कोटलिन दुनिया में, कक्षाओं में फ़ील्ड नहीं हो सकते हैं, बस गुण हैं। var कीवर्ड बताता है कि वैल के विपरीत, संपत्ति उत्परिवर्तनीय है। आइए एक उदाहरण देखें:

class Contact(var number: String) {

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

}

ज्यादा कोड नहीं है, लेकिन पर्दे के पीछे बहुत सारी चीजें हो रही हैं। हम इसके साथ कदम से कदम मिलाकर चलेंगे। सबसे पहले, हमने एक सार्वजनिक अंतिम वर्ग संपर्क बनाया।

यह प्राथमिक नियम है जिसका हमें सामना करना पड़ता है: यदि अन्यथा निर्दिष्ट नहीं किया गया है, तो कक्षाएं डिफ़ॉल्ट रूप से सार्वजनिक और अंतिम हैं (वैसे, वर्ग विधियों के लिए भी यही है)। यदि आप कक्षा से विरासत में प्राप्त करना चाहते हैं, तो इसे खुले कीवर्ड से चिह्नित करें।


0

यहां कोटलीन गेट्टर और सेटर का व्यावहारिक, वास्तविक दुनिया उदाहरण दिया गया है ( यहां अधिक विवरण देखें ):

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.