यह कोडलैब, प्रोग्रामर के लिए Kotlin बूटकैंप कोर्स का हिस्सा है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. अपनी जानकारी के हिसाब से, कुछ सेक्शन को सरसरी तौर पर पढ़ा जा सकता है. यह कोर्स उन प्रोग्रामर के लिए है जिन्हें ऑब्जेक्ट ओरिएंटेड लैंग्वेज के बारे में जानकारी है और जो Kotlin सीखना चाहते हैं.
परिचय
इस कोडलैब में, Kotlin प्रोग्राम बनाया जाता है. साथ ही, Kotlin में क्लास और ऑब्जेक्ट के बारे में जाना जाता है. अगर आपको ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग वाली कोई दूसरी लैंग्वेज आती है, तो आपको इस कॉन्टेंट के बारे में पहले से पता होगा. हालांकि, Kotlin में कुछ अहम अंतर हैं. इनकी वजह से, आपको कम कोड लिखना पड़ता है. इसमें आपको ऐब्सट्रैक्ट क्लास और इंटरफ़ेस डेलिगेशन के बारे में भी जानकारी मिलती है.
इस कोर्स में, एक सैंपल ऐप्लिकेशन बनाने के बजाय, अलग-अलग विषयों पर जानकारी दी गई है. हालांकि, ये विषय एक-दूसरे से जुड़े हुए हैं, लेकिन इन्हें इस तरह से डिज़ाइन किया गया है कि आप अपनी ज़रूरत के हिसाब से किसी भी विषय को पढ़ सकें. इन सभी उदाहरणों को एक साथ दिखाने के लिए, इनमें ऐक्वेरियम की थीम का इस्तेमाल किया गया है. अगर आपको एक्वेरियम की पूरी कहानी देखनी है, तो Udacity पर प्रोग्रामर के लिए Kotlin बूटकैंप कोर्स देखें.
आपको पहले से क्या पता होना चाहिए
- Kotlin की बुनियादी बातें, जैसे कि टाइप, ऑपरेटर, और लूपिंग
- Kotlin में फ़ंक्शन का सिंटैक्स
- ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के बारे में बुनियादी जानकारी
- IntelliJ IDEA या Android Studio जैसे आईडीई की बुनियादी बातें
आपको क्या सीखने को मिलेगा
- Kotlin में क्लास बनाने और प्रॉपर्टी ऐक्सेस करने का तरीका
- Kotlin में क्लास कंस्ट्रक्टर बनाने और उनका इस्तेमाल करने का तरीका
- सबक्लास बनाने का तरीका और इनहेरिटेंस कैसे काम करता है
- ऐब्सट्रैक्ट क्लास, इंटरफ़ेस, और इंटरफ़ेस डेलिगेशन के बारे में जानकारी
- डेटा क्लास बनाने और उनका इस्तेमाल करने का तरीका
- सिंगलटन, एनम, और सील की गई क्लास इस्तेमाल करने का तरीका
आपको क्या करना होगा
- प्रॉपर्टी के साथ क्लास बनाना
- किसी क्लास के लिए कंस्ट्रक्टर बनाना
- कोई सबक्लास बनाना
- ऐब्स्ट्रैक्ट क्लास और इंटरफ़ेस के उदाहरणों की जांच करना
- एक सामान्य डेटा क्लास बनाना
- सिंगलटन, एनम, और सील की गई क्लास के बारे में जानें
आपको प्रोग्रामिंग से जुड़े इन शब्दों के बारे में पहले से पता होना चाहिए:
- क्लास, ऑब्जेक्ट के लिए ब्लूप्रिंट होती हैं. उदाहरण के लिए,
Aquarium
क्लास, ऐक्वेरियम ऑब्जेक्ट बनाने के लिए ब्लूप्रिंट है. - ऑब्जेक्ट, क्लास के इंस्टेंस होते हैं. ऐक्वेरियम ऑब्जेक्ट, एक असल
Aquarium
होता है. - प्रॉपर्टी, क्लास की विशेषताएं होती हैं. जैसे, किसी
Aquarium
की लंबाई, चौड़ाई, और ऊंचाई. - तरीके, जिन्हें मेंबर फ़ंक्शन भी कहा जाता है, क्लास की सुविधाएं होती हैं. तरीके वे होते हैं जो ऑब्जेक्ट के साथ "किए" जा सकते हैं. उदाहरण के लिए, किसी
Aquarium
ऑब्जेक्ट कोfillWithWater()
किया जा सकता है. - इंटरफ़ेस एक ऐसा स्पेसिफ़िकेशन होता है जिसे कोई क्लास लागू कर सकती है. उदाहरण के लिए, साफ़-सफ़ाई करना, ऐक्वेरियम के अलावा अन्य ऑब्जेक्ट के लिए भी सामान्य है. साथ ही, अलग-अलग ऑब्जेक्ट के लिए साफ़-सफ़ाई आम तौर पर एक ही तरीके से की जाती है. इसलिए, आपके पास
Clean
नाम का एक इंटरफ़ेस हो सकता है, जोclean()
तरीके को तय करता है.Aquarium
क्लास,Clean
इंटरफ़ेस को लागू करके, मुलायम स्पंज से मछलीघर को साफ़ कर सकती है. - पैकेज, एक जैसे कोड को ग्रुप करने का तरीका है, ताकि उसे व्यवस्थित रखा जा सके या कोड की लाइब्रेरी बनाई जा सके. पैकेज बनाने के बाद, पैकेज के कॉन्टेंट को किसी दूसरी फ़ाइल में इंपोर्ट किया जा सकता है. साथ ही, उसमें मौजूद कोड और क्लास का फिर से इस्तेमाल किया जा सकता है.
इस टास्क में, आपको एक नया पैकेज और कुछ प्रॉपर्टी और एक तरीके वाली क्लास बनानी है.
पहला चरण: पैकेज बनाना
पैकेज की मदद से, अपने कोड को व्यवस्थित रखा जा सकता है.
- प्रोजेक्ट पैनल में, Hello Kotlin प्रोजेक्ट में जाकर, src फ़ोल्डर पर राइट क्लिक करें.
- नया > पैकेज चुनें और इसे
example.myapp
नाम दें.
दूसरा चरण: प्रॉपर्टी के साथ क्लास बनाना
क्लास को class
कीवर्ड से तय किया जाता है. साथ ही, क्लास के नाम की शुरुआत कैपिटल लेटर से होती है.
- example.myapp पैकेज पर राइट क्लिक करें.
- नई > Kotlin फ़ाइल / क्लास चुनें.
- टाइप में जाकर, क्लास चुनें और क्लास का नाम
Aquarium
रखें. IntelliJ IDEA, फ़ाइल में पैकेज का नाम शामिल करता है और आपके लिए एक खालीAquarium
क्लास बनाता है. Aquarium
क्लास में, चौड़ाई, ऊंचाई, और लंबाई (सेंटीमीटर में) के लिएvar
प्रॉपर्टी तय करें और उन्हें शुरू करें. प्रॉपर्टी को डिफ़ॉल्ट वैल्यू के साथ शुरू करें.
package example.myapp
class Aquarium {
var width: Int = 20
var height: Int = 40
var length: Int = 100
}
Kotlin, Aquarium
क्लास में तय की गई प्रॉपर्टी के लिए, अपने-आप गेटर और सेटर बना देता है. इसलिए, प्रॉपर्टी को सीधे तौर पर ऐक्सेस किया जा सकता है. उदाहरण के लिए, myAquarium.length
.
तीसरा चरण: main() फ़ंक्शन बनाना
main()
फ़ंक्शन को सेव करने के लिए, main.kt
नाम की एक नई फ़ाइल बनाएं.
- बाईं ओर मौजूद प्रोजेक्ट पैन में, example.myapp पैकेज पर राइट क्लिक करें.
- नई > Kotlin फ़ाइल / क्लास चुनें.
- टाइप ड्रॉपडाउन में, फ़ाइल को चुने हुए विकल्प के तौर पर रखें. इसके बाद, फ़ाइल का नाम
main.kt
रखें. IntelliJ IDEA में पैकेज का नाम शामिल होता है, लेकिन इसमें किसी फ़ाइल के लिए क्लास की परिभाषा शामिल नहीं होती है. buildAquarium()
फ़ंक्शन तय करें और इसके अंदरAquarium
का इंस्टेंस बनाएं. कोई इंस्टेंस बनाने के लिए, क्लास को इस तरह से रेफ़रंस करें जैसे कि वह कोई फ़ंक्शन हो,Aquarium()
. इससे क्लास के कंस्ट्रक्टर को कॉल किया जाता है औरAquarium
क्लास का इंस्टेंस बनाया जाता है. यह अन्य भाषाओं मेंnew
का इस्तेमाल करने जैसा ही है.main()
फ़ंक्शन तय करें औरbuildAquarium()
को कॉल करें.
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium()
}
fun main() {
buildAquarium()
}
चौथा चरण: कोई तरीका जोड़ना
Aquarium
क्लास में, एक्वेरियम की डाइमेंशन प्रॉपर्टी प्रिंट करने का तरीका जोड़ें.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
}
-
main.kt
में,buildAquarium()
में,myAquarium
परprintSize()
तरीके को कॉल करें.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
}
- अपने प्रोग्राम को चलाने के लिए,
main()
फ़ंक्शन के बगल में मौजूद हरे रंग के त्रिकोण पर क्लिक करें. नतीजे देखें.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm
buildAquarium()
में, ऊंचाई को 60 पर सेट करने के लिए कोड जोड़ें और डाइमेंशन की बदली हुई प्रॉपर्टी प्रिंट करें.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
myAquarium.height = 60
myAquarium.printSize()
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 100 cm Height: 60 cm
इस टास्क में, आपको क्लास के लिए कंस्ट्रक्टर बनाना है. साथ ही, प्रॉपर्टी के साथ काम करना जारी रखना है.
पहला चरण: कंस्ट्रक्टर बनाना
इस चरण में, आपको पहले टास्क में बनाई गई Aquarium
क्लास में एक कंस्ट्रक्टर जोड़ना होता है. पिछले उदाहरण में, Aquarium
के हर इंस्टेंस को एक ही डाइमेंशन के साथ बनाया गया है. डाइमेंशन बनाने के बाद, प्रॉपर्टी सेट करके उनमें बदलाव किया जा सकता है. हालांकि, शुरुआत में ही सही साइज़ का डाइमेंशन बनाना ज़्यादा आसान होता है.
कुछ प्रोग्रामिंग भाषाओं में, कंस्ट्रक्टर को क्लास में एक ऐसा तरीका बनाकर तय किया जाता है जिसका नाम क्लास के नाम जैसा ही होता है. Kotlin में, कंस्ट्रक्टर को सीधे तौर पर क्लास की परिभाषा में ही तय किया जाता है. इसमें पैरामीटर को पैरंटheses के अंदर इस तरह से तय किया जाता है जैसे क्लास कोई तरीका हो. Kotlin में फ़ंक्शन की तरह, इन पैरामीटर में डिफ़ॉल्ट वैल्यू शामिल हो सकती हैं.
- आपने पहले जो
Aquarium
क्लास बनाई थी उसमें क्लास की परिभाषा बदलें. इसमेंlength
,width
, औरheight
के लिए डिफ़ॉल्ट वैल्यू वाले तीन कंस्ट्रक्टर पैरामीटर शामिल करें. साथ ही, उन्हें उनसे जुड़ी प्रॉपर्टी असाइन करें.
class Aquarium(length: Int = 100, width: Int = 20, height: Int = 40) {
// Dimensions in cm
var length: Int = length
var width: Int = width
var height: Int = height
...
}
- Kotlin में, प्रॉपर्टी को सीधे कंस्ट्रक्टर के साथ तय किया जा सकता है. इसके लिए,
var
याval
का इस्तेमाल किया जाता है. साथ ही, Kotlin अपने-आप गेटर और सेटर भी बनाता है. इसके बाद, क्लास के मुख्य हिस्से में मौजूद प्रॉपर्टी डेफ़िनिशन को हटाया जा सकता है.
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40) {
...
}
- उस कंस्ट्रक्टर की मदद से
Aquarium
ऑब्जेक्ट बनाते समय, कोई भी आर्ग्युमेंट तय न करके डिफ़ॉल्ट वैल्यू पाई जा सकती हैं. इसके अलावा, कुछ आर्ग्युमेंट तय करके या सभी आर्ग्युमेंट तय करके, अपनी पसंद के साइज़ काAquarium
बनाया जा सकता है.buildAquarium()
फ़ंक्शन में, नाम वाले पैरामीटर का इस्तेमाल करकेAquarium
ऑब्जेक्ट बनाने के अलग-अलग तरीके आज़माएं.
fun buildAquarium() {
val aquarium1 = Aquarium()
aquarium1.printSize()
// default height and length
val aquarium2 = Aquarium(width = 25)
aquarium2.printSize()
// default width
val aquarium3 = Aquarium(height = 35, length = 110)
aquarium3.printSize()
// everything custom
val aquarium4 = Aquarium(width = 25, height = 35, length = 110)
aquarium4.printSize()
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 25 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 110 cm Height: 35 cm Width: 25 cm Length: 110 cm Height: 35 cm
ध्यान दें कि आपको कंस्ट्रक्टर को ओवरलोड करने और इन सभी मामलों के लिए अलग-अलग वर्शन लिखने की ज़रूरत नहीं पड़ी. साथ ही, अन्य कॉम्बिनेशन के लिए कुछ और वर्शन लिखने की भी ज़रूरत नहीं पड़ी. Kotlin, डिफ़ॉल्ट वैल्यू और नाम वाले पैरामीटर से ज़रूरी चीज़ें बनाता है.
दूसरा चरण: init ब्लॉक जोड़ना
ऊपर दिए गए उदाहरण कंस्ट्रक्टर, सिर्फ़ प्रॉपर्टी के बारे में बताते हैं और उन्हें एक्सप्रेशन की वैल्यू असाइन करते हैं. अगर आपके कंस्ट्रक्टर को ज़्यादा शुरुआती कोड की ज़रूरत है, तो उसे एक या उससे ज़्यादा init
ब्लॉक में रखा जा सकता है. इस चरण में, आपको Aquarium
क्लास में कुछ init
ब्लॉक जोड़ने हैं.
Aquarium
क्लास में, एकinit
ब्लॉक जोड़ें, ताकि यह प्रिंट किया जा सके कि ऑब्जेक्ट शुरू हो रहा है. साथ ही, एक दूसरा ब्लॉक जोड़ें, ताकि लीटर में वॉल्यूम प्रिंट किया जा सके.
class Aquarium (var length: Int = 100, var width: Int = 20, var height: Int = 40) {
init {
println("aquarium initializing")
}
init {
// 1 liter = 1000 cm^3
println("Volume: ${width * length * height / 1000} l")
}
}
- प्रोग्राम चलाएं और आउटपुट देखें.
aquarium initializing
Volume: 80 l
Width: 20 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 100 l
Width: 25 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 77 l
Width: 20 cm Length: 110 cm Height: 35 cm
aquarium initializing
Volume: 96 l
Width: 25 cm Length: 110 cm Height: 35 cm
ध्यान दें कि init
ब्लॉक, क्लास की परिभाषा में दिखने वाले क्रम में एक्ज़ीक्यूट किए जाते हैं. साथ ही, कंस्ट्रक्टर को कॉल करने पर, ये सभी ब्लॉक एक्ज़ीक्यूट किए जाते हैं.
तीसरा चरण: सेकंडरी कंस्ट्रक्टर के बारे में जानें
इस चरण में, आपको सेकंडरी कंस्ट्रक्टर के बारे में जानकारी मिलती है. साथ ही, आपको अपनी क्लास में एक कंस्ट्रक्टर जोड़ने का तरीका भी पता चलता है. मुख्य कंस्ट्रक्टर के साथ-साथ, Kotlin क्लास में एक या उससे ज़्यादा सेकंडरी कंस्ट्रक्टर भी हो सकते हैं. मुख्य कंस्ट्रक्टर में एक या उससे ज़्यादा init
ब्लॉक हो सकते हैं. सेकंडरी कंस्ट्रक्टर की मदद से, कंस्ट्रक्टर ओवरलोडिंग की जा सकती है. इसका मतलब है कि अलग-अलग आर्ग्युमेंट वाले कंस्ट्रक्टर बनाए जा सकते हैं.
Aquarium
क्लास में, एक सेकंडरी कंस्ट्रक्टर जोड़ें. यह कंस्ट्रक्टर,constructor
कीवर्ड का इस्तेमाल करके, मछलियों की संख्या को अपने तर्क के तौर पर लेता है. मछलियों की संख्या के आधार पर, ऐक्वेरियम के अनुमानित वॉल्यूम के लिए, लीटर मेंval
टैंक प्रॉपर्टी बनाएं. हर मछली के लिए दो लीटर (2,000 cm^3) पानी लें. साथ ही, थोड़ा ज़्यादा पानी लें, ताकि वह बाहर न गिरे.
constructor(numberOfFish: Int) : this() {
// 2,000 cm^3 per fish + extra room so water doesn't spill
val tank = numberOfFish * 2000 * 1.1
}
- सेकंडरी कंस्ट्रक्टर में, लंबाई और चौड़ाई को पहले जैसा ही रखें (जिन्हें प्राइमरी कंस्ट्रक्टर में सेट किया गया था). इसके बाद, टैंक को दिए गए वॉल्यूम का बनाने के लिए ज़रूरी ऊंचाई का हिसाब लगाएं.
// calculate the height needed
height = (tank / (length * width)).toInt()
buildAquarium()
फ़ंक्शन में, अपने नए सेकंडरी कंस्ट्रक्टर का इस्तेमाल करकेAquarium
बनाने के लिए एक कॉल जोड़ें. साइज़ और वॉल्यूम प्रिंट करें.
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
println("Volume: ${aquarium6.width * aquarium6.length * aquarium6.height / 1000} l")
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ aquarium initializing Volume: 80 l Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
ध्यान दें कि वॉल्यूम को दो बार प्रिंट किया गया है. पहली बार, सेकंडरी कंस्ट्रक्टर के एक्ज़ीक्यूट होने से पहले, मुख्य कंस्ट्रक्टर में मौजूद init
ब्लॉक से और दूसरी बार, buildAquarium()
में मौजूद कोड से.
constructor
कीवर्ड को मुख्य कंस्ट्रक्टर में भी शामिल किया जा सकता था. हालांकि, ज़्यादातर मामलों में ऐसा करना ज़रूरी नहीं होता.
चौथा चरण: नई प्रॉपर्टी गेटर जोड़ना
इस चरण में, आपको एक एक्सप्लिसिट प्रॉपर्टी गेटर जोड़ना होता है. प्रॉपर्टी तय करते समय, Kotlin अपने-आप गेटर और सेटर तय करता है. हालांकि, कभी-कभी किसी प्रॉपर्टी की वैल्यू को अडजस्ट करने या उसका हिसाब लगाने की ज़रूरत होती है. उदाहरण के लिए, ऊपर आपने Aquarium
का वॉल्यूम प्रिंट किया है. वॉल्यूम को प्रॉपर्टी के तौर पर उपलब्ध कराया जा सकता है. इसके लिए, आपको एक वैरिएबल और एक गेटर तय करना होगा. volume
को कैलकुलेट करना ज़रूरी है. इसलिए, गेटर को कैलकुलेट की गई वैल्यू को वापस भेजना होगा. इसके लिए, एक लाइन वाला फ़ंक्शन इस्तेमाल किया जा सकता है.
Aquarium
क्लास में,volume
नाम कीInt
प्रॉपर्टी को तय करें. साथ ही, एकget()
तरीका तय करें, जो अगली लाइन में वॉल्यूम का हिसाब लगाता है.
val volume: Int
get() = width * height * length / 1000 // 1000 cm^3 = 1 l
- आवाज़ को प्रिंट करने वाले
init
ब्लॉक को हटाएं. buildAquarium()
में मौजूद, आवाज़ को प्रिंट करने वाले कोड को हटाएं.printSize()
तरीके में, वॉल्यूम को प्रिंट करने के लिए एक लाइन जोड़ें.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm "
)
// 1 l = 1000 cm^3
println("Volume: $volume l")
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ aquarium initializing Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
डाइमेंशन और वॉल्यूम पहले की तरह ही हैं. हालांकि, वॉल्यूम को सिर्फ़ एक बार प्रिंट किया जाता है. ऐसा तब होता है, जब प्राइमरी कंस्ट्रक्टर और सेकंडरी कंस्ट्रक्टर, दोनों ऑब्जेक्ट को पूरी तरह से शुरू कर देते हैं.
पांचवां चरण: प्रॉपर्टी सेटर जोड़ना
इस चरण में, वॉल्यूम के लिए एक नया प्रॉपर्टी सेटर बनाया जाता है.
Aquarium
क्लास में,volume
कोvar
में बदलें, ताकि इसे एक से ज़्यादा बार सेट किया जा सके.- गेटर के नीचे
set()
प्रॉपर्टी के लिए सेटर जोड़ें. इसके लिए,set()
तरीके को जोड़ें. यह पानी की मात्रा के आधार पर ऊंचाई की फिर से गणना करता है.volume
परंपरा के मुताबिक, सेटर पैरामीटर का नामvalue
होता है. हालांकि, अगर चाहें, तो इसे बदला जा सकता है.
var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
-
buildAquarium()
में, कोड जोड़कर एक्वेरियम में पानी की मात्रा 70 लीटर पर सेट करें. नए साइज़ में प्रिंट करें.
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
aquarium6.volume = 70
aquarium6.printSize()
}
- अपने प्रोग्राम को फिर से चलाएं और ऊंचाई और वॉल्यूम में हुए बदलाव को देखें.
⇒ aquarium initialized
Width: 20 cm Length: 100 cm Height: 31 cm
Volume: 62 l
Width: 20 cm Length: 100 cm Height: 35 cm
Volume: 70 l
कोड में अब तक, public
या private
जैसे कोई भी विज़िबिलिटी मॉडिफ़ायर नहीं हैं. ऐसा इसलिए है, क्योंकि Kotlin में डिफ़ॉल्ट रूप से सब कुछ पब्लिक होता है. इसका मतलब है कि हर चीज़ को हर जगह ऐक्सेस किया जा सकता है. इसमें क्लास, मेथड, प्रॉपर्टी, और मेंबर वैरिएबल शामिल हैं.
Kotlin में, क्लास, ऑब्जेक्ट, इंटरफ़ेस, कंस्ट्रक्टर, फ़ंक्शन, प्रॉपर्टी, और उनके सेटर के लिए विज़िबिलिटी मॉडिफ़ायर इस्तेमाल किए जा सकते हैं:
public
का मतलब है, क्लास के बाहर दिखती है. डिफ़ॉल्ट रूप से, सब कुछ पब्लिक होता है. इसमें क्लास के वैरिएबल और मेथड शामिल हैं.internal
का मतलब है कि वह सिर्फ़ उस मॉड्यूल में दिखेगी. मॉड्यूल, कंपाइल की गई Kotlin फ़ाइलों का एक सेट होता है. उदाहरण के लिए, कोई लाइब्रेरी या ऐप्लिकेशन.private
का मतलब है कि वह सिर्फ़ क्लास के अंदर दिखेगी (या सोर्स फ़ाइल में, अगर फ़ंक्शन इस्तेमाल किए जा रहे हैं).protected
,private
की ही तरह है, लेकिन इसे सब-क्लास में भी देखा जा सकेगा.
ज़्यादा जानकारी के लिए, Kotlin के दस्तावेज़ में Visibility Modifiers देखें.
सदस्यता वाले वैरिएबल
किसी क्लास में मौजूद प्रॉपर्टी या सदस्य वैरिएबल, डिफ़ॉल्ट रूप से public
होते हैं. अगर उन्हें var
के साथ तय किया जाता है, तो उनमें बदलाव किया जा सकता है. इसका मतलब है कि उन्हें पढ़ा और लिखा जा सकता है. अगर आपने उन्हें val
के साथ तय किया है, तो वे शुरू होने के बाद सिर्फ़ पढ़े जा सकते हैं.
अगर आपको ऐसी प्रॉपर्टी चाहिए जिसे आपका कोड पढ़ या लिख सकता है, लेकिन बाहर का कोड सिर्फ़ पढ़ सकता है, तो प्रॉपर्टी और उसके getter को सार्वजनिक के तौर पर छोड़ा जा सकता है. साथ ही, setter को निजी के तौर पर घोषित किया जा सकता है. इसे नीचे दिखाया गया है.
var volume: Int
get() = width * height * length / 1000
private set(value) {
height = (value * 1000) / (width * length)
}
इस टास्क में, आपको Kotlin में सबक्लास और इनहेरिटेंस के काम करने के तरीके के बारे में जानकारी मिलेगी. ये अन्य भाषाओं में दिखने वाले नतीजों की तरह ही होते हैं. हालांकि, इनमें कुछ अंतर होते हैं.
Kotlin में, डिफ़ॉल्ट रूप से क्लास को सबक्लास नहीं किया जा सकता. इसी तरह, प्रॉपर्टी और सदस्य वैरिएबल को सबक्लास से बदला नहीं जा सकता. हालांकि, इन्हें ऐक्सेस किया जा सकता है.
किसी क्लास को सबक्लास करने की अनुमति देने के लिए, उसे open
के तौर पर मार्क करना ज़रूरी है. इसी तरह, सबक्लास में प्रॉपर्टी और मेंबर वैरिएबल को ओवरराइड करने के लिए, उन्हें open
के तौर पर मार्क करना ज़रूरी है. क्लास के इंटरफ़ेस के हिस्से के तौर पर, लागू करने से जुड़ी जानकारी को गलती से लीक होने से रोकने के लिए, open
कीवर्ड का इस्तेमाल करना ज़रूरी है.
पहला चरण: Aquarium क्लास को चालू करें
इस चरण में, आपको Aquarium
क्लास open
बनानी होगी, ताकि अगले चरण में इसे बदला जा सके.
Aquarium
क्लास और उसकी सभी प्रॉपर्टी कोopen
कीवर्ड के साथ मार्क करें.
open class Aquarium (open var length: Int = 100, open var width: Int = 20, open var height: Int = 40) {
open var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
shape
वैल्यू वाली ओपनshape
प्रॉपर्टी जोड़ें."rectangle"
open val shape = "rectangle"
- ऐसी खुली
water
प्रॉपर्टी जोड़ें जिसमें गैटर हो. यह गैटर,Aquarium
के वॉल्यूम का 90% दिखाता हो.
open var water: Double = 0.0
get() = volume * 0.9
- आकार और पानी की मात्रा को वॉल्यूम के प्रतिशत के तौर पर प्रिंट करने के लिए,
printSize()
तरीके में कोड जोड़ें.
fun printSize() {
println(shape)
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
// 1 l = 1000 cm^3
println("Volume: $volume l Water: $water l (${water/volume*100.0}% full)")
}
buildAquarium()
में, कोड बदलकरwidth = 25
,length = 25
, औरheight = 40
के साथAquarium
बनाएं.
fun buildAquarium() {
val aquarium6 = Aquarium(length = 25, width = 25, height = 40)
aquarium6.printSize()
}
- अपने प्रोग्राम को चलाएं और नए आउटपुट को देखें.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full)
दूसरा चरण: सबक्लास बनाना
Aquarium
की एक सबक्लासTowerTank
बनाएं. इसमें रेक्टैंगुलर टैंक के बजाय, गोल सिलेंडर टैंक का इस्तेमाल किया जाता है.TowerTank
कोAquarium
के नीचे जोड़ा जा सकता है, क्योंकिAquarium
क्लास की तरह ही एक ही फ़ाइल में दूसरी क्लास जोड़ी जा सकती है.- कंस्ट्रक्टर में तय की गई
height
प्रॉपर्टी कोTowerTank
में ओवरराइड करें. किसी प्रॉपर्टी को बदलने के लिए, सबक्लास मेंoverride
कीवर्ड का इस्तेमाल करें.
TowerTank
के कंस्ट्रक्टर कोdiameter
लेने के लिए बनाएं.Aquarium
सुपरक्लास में कंस्ट्रक्टर को कॉल करते समय,length
औरwidth
, दोनों के लिएdiameter
का इस्तेमाल करें.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
- सिलिंडर का हिसाब लगाने के लिए, वॉल्यूम प्रॉपर्टी को बदलें. बेलन का फ़ॉर्मूला, पाई गुणा त्रिज्या का वर्ग गुणा ऊँचाई होता है. आपको
java.lang.Math
सेPI
कॉन्स्टेंट इंपोर्ट करना होगा.
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
TowerTank
में,water
प्रॉपर्टी को बदलकर वॉल्यूम का 80% करें.
override var water = volume * 0.8
shape
को"cylinder"
के तौर पर बदलें.
override val shape = "cylinder"
- आपकी फ़ाइनल
TowerTank
क्लास, नीचे दिए गए कोड की तरह दिखनी चाहिए.
Aquarium.kt
:
package example.myapp
import java.lang.Math.PI
... // existing Aquarium class
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
override var water = volume * 0.8
override val shape = "cylinder"
}
buildAquarium()
में, 25 सेमी व्यास और 45 सेमी ऊंचाई वालाTowerTank
बनाओ. साइज़ प्रिंट करें.
main.kt:
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium(width = 25, length = 25, height = 40)
myAquarium.printSize()
val myTower = TowerTank(diameter = 25, height = 40)
myTower.printSize()
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full) aquarium initializing cylinder Width: 25 cm Length: 25 cm Height: 40 cm Volume: 18 l Water: 14.4 l (80.0% full)
कभी-कभी आपको कुछ मिलती-जुलती क्लास के लिए, सामान्य व्यवहार या प्रॉपर्टी तय करनी होती हैं. Kotlin में ऐसा करने के दो तरीके हैं: इंटरफ़ेस और ऐब्सट्रैक्ट क्लास. इस टास्क में, आपको एक ऐब्स्ट्रैक्ट AquariumFish
क्लास बनानी है. इसमें ऐसी प्रॉपर्टी शामिल होंगी जो सभी मछलियों में एक जैसी होती हैं. आपने FishAction
नाम का एक इंटरफ़ेस बनाया है, ताकि सभी मछलियों के लिए एक जैसा व्यवहार तय किया जा सके.
- न तो ऐब्स्ट्रैक्ट क्लास और न ही इंटरफ़ेस को अपने-आप इंस्टैंशिएट किया जा सकता है. इसका मतलब है कि सीधे तौर पर उन टाइप के ऑब्जेक्ट नहीं बनाए जा सकते.
- ऐब्स्ट्रैक्ट क्लास में कंस्ट्रक्टर होते हैं.
- इंटरफ़ेस में कोई कंस्ट्रक्टर लॉजिक नहीं हो सकता. साथ ही, वे किसी भी स्थिति को सेव नहीं कर सकते.
पहला चरण. ऐब्स्ट्रैक्ट क्लास बनाना
- example.myapp में जाकर, एक नई फ़ाइल
AquariumFish.kt
बनाएं. AquariumFish
नाम की क्लास बनाएं और उसेabstract
के तौर पर मार्क करें.- एक
String
प्रॉपर्टी,color
जोड़ें और उसेabstract
के तौर पर मार्क करें.
package example.myapp
abstract class AquariumFish {
abstract val color: String
}
AquariumFish
,Shark
, औरPlecostomus
की दो सबक्लास बनाएं.color
ऐब्स्ट्रैक्ट है. इसलिए, सब-क्लास को इसे लागू करना होगा.Shark
को स्लेटी औरPlecostomus
को सुनहरा रंग दें.
class Shark: AquariumFish() {
override val color = "gray"
}
class Plecostomus: AquariumFish() {
override val color = "gold"
}
- अपनी क्लास को टेस्ट करने के लिए, main.kt में
makeFish()
फ़ंक्शन बनाएं.Shark
औरPlecostomus
को इंस्टैंशिएट करें. इसके बाद, हर एक का रंग प्रिंट करें. main()
में मौजूद अपने पिछले टेस्ट कोड को मिटाएं औरmakeFish()
में कॉल जोड़ें. आपका कोड, यहां दिए गए कोड की तरह दिखना चाहिए.
main.kt
:
package example.myapp
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
println("Plecostomus: ${pleco.color}")
}
fun main () {
makeFish()
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ Shark: gray Plecostomus: gold
इस डायग्राम में, Shark
क्लास और Plecostomus
क्लास को दिखाया गया है. ये दोनों, ऐब्स्ट्रैक्ट क्लास AquariumFish
की सबक्लास हैं.
दूसरा चरण. इंटरफ़ेस बनाना
- AquariumFish.kt में,
eat()
तरीके के साथFishAction
नाम का इंटरफ़ेस बनाएं.
interface FishAction {
fun eat()
}
- हर सबक्लास में
FishAction
जोड़ें. साथ ही,eat()
को लागू करें, ताकि यह प्रिंट कर सके कि मछली क्या करती है.
class Shark: AquariumFish(), FishAction {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
class Plecostomus: AquariumFish(), FishAction {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
makeFish()
फ़ंक्शन में, बनाई गई हर मछली को कुछ खाने के लिए दें. इसके लिए,eat()
को कॉल करें.
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
shark.eat()
println("Plecostomus: ${pleco.color}")
pleco.eat()
}
- प्रोग्राम चलाएं और आउटपुट देखें.
⇒ Shark: gray hunt and eat fish Plecostomus: gold eat algae
इस डायग्राम में Shark
क्लास और Plecostomus
क्लास को दिखाया गया है. ये दोनों क्लास, FishAction
इंटरफ़ेस से बनी हैं और इसे लागू करती हैं.
ऐब्सट्रैक्ट क्लास और इंटरफ़ेस का इस्तेमाल कब करना चाहिए
ऊपर दिए गए उदाहरण आसान हैं. हालांकि, जब आपके पास एक-दूसरे से जुड़ी कई क्लास होती हैं, तो ऐब्स्ट्रैक्ट क्लास और इंटरफ़ेस की मदद से, अपने डिज़ाइन को ज़्यादा साफ़-सुथरा, व्यवस्थित, और बनाए रखने में आसान बनाया जा सकता है.
ऊपर बताया गया है कि ऐब्स्ट्रैक्ट क्लास में कंस्ट्रक्टर हो सकते हैं, जबकि इंटरफ़ेस में नहीं. हालांकि, इसके अलावा ये दोनों काफ़ी मिलते-जुलते हैं. इसलिए, आपको इनमें से हर एक का इस्तेमाल कब करना चाहिए?
किसी क्लास को कंपोज़ करने के लिए इंटरफ़ेस का इस्तेमाल करने पर, क्लास में मौजूद क्लास इंस्टेंस की मदद से क्लास की सुविधाओं को बढ़ाया जाता है. कंपोज़िशन की मदद से, कोड को दोबारा इस्तेमाल करना और उसके बारे में सोचना, ऐब्स्ट्रैक्ट क्लास से इनहेरिटेंस की तुलना में ज़्यादा आसान होता है. इसके अलावा, किसी क्लास में एक से ज़्यादा इंटरफ़ेस इस्तेमाल किए जा सकते हैं. हालांकि, सिर्फ़ एक ऐब्स्ट्रैक्ट क्लास से सबक्लास किया जा सकता है.
कंपोज़िशन से अक्सर बेहतर इनकैप्सुलेशन, कम कपलिंग (एक-दूसरे पर निर्भरता), साफ़ इंटरफ़ेस, और ज़्यादा इस्तेमाल किया जा सकने वाला कोड मिलता है. इन वजहों से, इंटरफ़ेस के साथ कंपोज़िशन का इस्तेमाल करना बेहतर डिज़ाइन है. दूसरी ओर, कुछ समस्याओं के लिए ऐब्स्ट्रैक्ट क्लास से इनहेरिटेंस, एक बेहतर विकल्प होता है. इसलिए, आपको कंपोज़िशन का इस्तेमाल करना चाहिए. हालांकि, अगर इनहेरिटेंस का इस्तेमाल करना ज़रूरी हो, तो Kotlin में ऐसा किया जा सकता है!
- अगर आपके पास कई तरीके हैं और एक या दो डिफ़ॉल्ट लागू करने के तरीके हैं, तो इंटरफ़ेस का इस्तेमाल करें. उदाहरण के लिए,
AquariumAction
में दिए गए तरीके का इस्तेमाल करें.
interface AquariumAction {
fun eat()
fun jump()
fun clean()
fun catchFish()
fun swim() {
println("swim")
}
}
- जब किसी क्लास को पूरा न किया जा सके, तब ऐब्स्ट्रैक्ट क्लास का इस्तेमाल करें. उदाहरण के लिए,
AquariumFish
क्लास पर वापस जाएं. यहां सभीAquariumFish
,FishAction
को लागू कर सकते हैं. साथ ही,eat
के लिए डिफ़ॉल्ट तौर पर लागू होने वाला कोड उपलब्ध करा सकते हैं. हालांकि,color
को ऐब्स्ट्रैक्ट छोड़ दें, क्योंकि मछली के लिए कोई डिफ़ॉल्ट रंग नहीं होता.
interface FishAction {
fun eat()
}
abstract class AquariumFish: FishAction {
abstract val color: String
override fun eat() = println("yum")
}
पिछले टास्क में, ऐब्स्ट्रैक्ट क्लास, इंटरफ़ेस, और कंपोज़िशन के बारे में बताया गया था. इंटरफ़ेस डेलिगेशन एक बेहतर तकनीक है. इसमें किसी इंटरफ़ेस के तरीकों को हेल्पर (या डेलिगेट) ऑब्जेक्ट लागू करता है. इसके बाद, इसका इस्तेमाल क्लास करती है. यह तकनीक तब काम आ सकती है, जब आपको किसी इंटरफ़ेस का इस्तेमाल, एक जैसी नहीं बल्कि अलग-अलग क्लास में करना हो. इसके लिए, आपको इंटरफ़ेस की ज़रूरी फ़ंक्शनैलिटी को किसी अलग हेल्पर क्लास में जोड़ना होगा. इसके बाद, हर क्लास, हेल्पर क्लास के इंस्टेंस का इस्तेमाल करके फ़ंक्शनैलिटी को लागू करेगी.
इस टास्क में, इंटरफ़ेस डेलिगेशन का इस्तेमाल करके किसी क्लास में फ़ंक्शन जोड़ा जाता है.
पहला चरण: नया इंटरफ़ेस बनाना
- AquariumFish.kt में,
AquariumFish
क्लास हटाएं.AquariumFish
क्लास से इनहेरिट करने के बजाय,Plecostomus
औरShark
, मछली की गतिविधि और उसके रंग, दोनों के लिए इंटरफ़ेस लागू करने वाले हैं. - एक नया इंटरफ़ेस,
FishColor
बनाएं, जो रंग को स्ट्रिंग के तौर पर तय करता है.
interface FishColor {
val color: String
}
- दो इंटरफ़ेस,
FishAction
, औरFishColor
लागू करने के लिए,Plecostomus
बदलें. आपकोFishColor
सेcolor
औरFishAction
सेeat()
को बदलना होगा.
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
AquariumFish
से इनहेरिट करने के बजाय,Shark
क्लास को बदलकरFishAction
औरFishColor
, दोनों इंटरफ़ेस लागू करें.
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
- आपका पूरा कोड कुछ ऐसा दिखना चाहिए:
package example.myapp
interface FishAction {
fun eat()
}
interface FishColor {
val color: String
}
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
दूसरा चरण: सिंगलटन क्लास बनाना
इसके बाद, डेलिगेशन के लिए सेटअप लागू किया जाता है. इसके लिए, एक हेल्पर क्लास बनाई जाती है, जो FishColor
को लागू करती है. आपने GoldColor
नाम की एक बुनियादी क्लास बनाई है, जो FishColor
को लागू करती है. यह सिर्फ़ यह बताती है कि इसका रंग सुनहरा है.
GoldColor
के एक से ज़्यादा इंस्टेंस बनाने का कोई मतलब नहीं है, क्योंकि वे सभी एक ही काम करेंगे. इसलिए, Kotlin में ऐसी क्लास का एलान किया जा सकता है जिसमें class
के बजाय object
कीवर्ड का इस्तेमाल करके, सिर्फ़ एक इंस्टेंस बनाया जा सकता है. Kotlin उस एक इंस्टेंस को बनाएगा. साथ ही, उस इंस्टेंस को क्लास के नाम से रेफ़र किया जाएगा. इसके बाद, अन्य सभी ऑब्जेक्ट सिर्फ़ इस एक इंस्टेंस का इस्तेमाल कर सकते हैं. इस क्लास के अन्य इंस्टेंस बनाने का कोई तरीका नहीं है. अगर आपको सिंगलटन पैटर्न के बारे में पता है, तो Kotlin में सिंगलटन को इस तरह लागू किया जाता है.
- AquariumFish.kt में,
GoldColor
के लिए एक ऑब्जेक्ट बनाएं. रंग को बदलें.
object GoldColor : FishColor {
override val color = "gold"
}
तीसरा चरण: FishColor के लिए इंटरफ़ेस डेलिगेशन जोड़ना
अब इंटरफ़ेस डेलिगेशन का इस्तेमाल किया जा सकता है.
- AquariumFish.kt में,
Plecostomus
सेcolor
का ओवरराइड हटाएं. Plecostomus
क्लास को बदलकरGoldColor
करें, ताकि उसका रंगGoldColor
से मिल सके. इसके लिए, क्लास के एलान मेंby GoldColor
जोड़ें और डेलिगेशन बनाएं. इसका मतलब है किFishColor
को लागू करने के बजाय,GoldColor
की ओर से उपलब्ध कराए गए तरीके का इस्तेमाल करें. इसलिए, जब भीcolor
को ऐक्सेस किया जाता है, तो इसेGoldColor
को सौंप दिया जाता है.
class Plecostomus: FishAction, FishColor by GoldColor {
override fun eat() {
println("eat algae")
}
}
क्लास के हिसाब से, सभी प्लेको सुनहरे रंग के होंगे. हालांकि, ये मछलियां कई रंगों में मिलती हैं. इसके लिए, कंस्ट्रक्टर पैरामीटर में रंग की जानकारी जोड़ें. साथ ही, Plecostomus
के लिए डिफ़ॉल्ट रंग के तौर पर GoldColor
को सेट करें.
Plecostomus
क्लास को बदलकर, कंस्ट्रक्टर के साथfishColor
में पास किया गया क्लास करें. साथ ही, इसे डिफ़ॉल्ट रूप सेGoldColor
पर सेट करें. प्रतिनिधि के तौर पर काम करने की अनुमति कोby GoldColor
से बदलकरby fishColor
करें.
class Plecostomus(fishColor: FishColor = GoldColor): FishAction,
FishColor by fishColor {
override fun eat() {
println("eat algae")
}
}
चौथा चरण: FishAction के लिए इंटरफ़ेस डेलिगेशन जोड़ना
इसी तरह, FishAction
के लिए इंटरफ़ेस डेलिगेशन का इस्तेमाल किया जा सकता है.
- AquariumFish.kt में,
PrintingFishAction
क्लास बनाएं. यहFishAction
को लागू करती है. इसमेंString
औरfood
शामिल हैं. इसके बाद, यह प्रिंट करती है कि मछली क्या खाती है.
class PrintingFishAction(val food: String) : FishAction {
override fun eat() {
println(food)
}
}
Plecostomus
क्लास में, ओवरराइड फ़ंक्शनeat()
को हटाएं, क्योंकि आपको इसे डेलिगेशन से बदलना है.Plecostomus
के एलान में,FishAction
कोPrintingFishAction
को सौंपें और"eat algae"
पास करें.- सभी डेलिगेशन के साथ,
Plecostomus
क्लास के मुख्य हिस्से में कोई कोड नहीं है. इसलिए,{}
को हटा दें, क्योंकि सभी ओवरराइड इंटरफ़ेस डेलिगेशन से मैनेज किए जाते हैं
class Plecostomus (fishColor: FishColor = GoldColor):
FishAction by PrintingFishAction("eat algae"),
FishColor by fishColor
इस डायग्राम में, Shark
और Plecostomus
क्लास को दिखाया गया है. ये दोनों, PrintingFishAction
और FishColor
इंटरफ़ेस से बनी हैं. हालांकि, ये इंटरफ़ेस को लागू करने का काम सौंपती हैं.
इंटरफ़ेस डेलिगेशन एक बेहतरीन सुविधा है. इसलिए, जब भी आपको किसी दूसरी भाषा में ऐब्स्ट्रैक्ट क्लास का इस्तेमाल करना हो, तब आपको आम तौर पर यह सोचना चाहिए कि इसका इस्तेमाल कैसे किया जाए. इसकी मदद से, कई सबक्लास बनाने के बजाय, कंपोज़िशन का इस्तेमाल करके व्यवहार को प्लग इन किया जा सकता है. हर सबक्लास अलग-अलग तरीके से काम करता है.
डेटा क्लास, कुछ अन्य भाषाओं में struct
की तरह होती है. इसका इस्तेमाल मुख्य रूप से कुछ डेटा को सेव करने के लिए किया जाता है. हालांकि, डेटा क्लास ऑब्जेक्ट अब भी एक ऑब्जेक्ट होता है. Kotlin डेटा क्लास ऑब्जेक्ट के कुछ अतिरिक्त फ़ायदे हैं. जैसे, प्रिंट करने और कॉपी करने की सुविधाएं. इस टास्क में, आपको एक सामान्य डेटा क्लास बनानी है. साथ ही, यह जानना है कि Kotlin, डेटा क्लास के लिए क्या-क्या सुविधाएं देता है.
पहला चरण: डेटा क्लास बनाना
- नया कोड रखने के लिए, example.myapp पैकेज में नया पैकेज
decor
जोड़ें. प्रोजेक्ट पैन में मौजूद example.myapp पर राइट क्लिक करें. इसके बाद, File > New > Package को चुनें. - पैकेज में,
Decoration
नाम की एक नई क्लास बनाएं.
package example.myapp.decor
class Decoration {
}
- किसी क्लास को
Decoration
डेटा क्लास बनाने के लिए, क्लास के एलान से पहलेdata
कीवर्ड का इस्तेमाल करें. - क्लास को कुछ डेटा देने के लिए,
String
नाम कीString
प्रॉपर्टी जोड़ें.rocks
data class Decoration(val rocks: String) {
}
- क्लास से बाहर फ़ाइल में,
makeDecorations()
फ़ंक्शन जोड़ें. इससे"granite"
के साथDecoration
का इंस्टेंस बनाया और प्रिंट किया जा सकता है.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
}
makeDecorations()
को कॉल करने के लिए,main()
फ़ंक्शन जोड़ें और अपना प्रोग्राम चलाएं. ध्यान दें कि यह एक डेटा क्लास है, इसलिए इससे काम का आउटपुट जनरेट हुआ है.
⇒ Decoration(rocks=granite)
makeDecorations()
में, "स्लेट" वाले दो औरDecoration
ऑब्जेक्ट इंस्टैंशिएट करें और उन्हें प्रिंट करें.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
val decoration2 = Decoration("slate")
println(decoration2)
val decoration3 = Decoration("slate")
println(decoration3)
}
makeDecorations()
में, एक प्रिंट स्टेटमेंट जोड़ें. यह स्टेटमेंट,decoration1
की तुलनाdecoration2
से करने पर मिले नतीजे को प्रिंट करता है. साथ ही, एक और स्टेटमेंट जोड़ें, जोdecoration3
की तुलनाdecoration2
से करने पर मिले नतीजे को प्रिंट करता है. डेटा क्लास के ज़रिए उपलब्ध कराए गए equals() तरीके का इस्तेमाल करें.
println (decoration1.equals(decoration2))
println (decoration3.equals(decoration2))
- अपना कोड लागू करें.
⇒ Decoration(rocks=granite) Decoration(rocks=slate) Decoration(rocks=slate) false true
दूसरा चरण. डीस्ट्रक्चरिंग का इस्तेमाल करना
किसी डेटा ऑब्जेक्ट की प्रॉपर्टी पाने और उन्हें वैरिएबल को असाइन करने के लिए, उन्हें एक-एक करके असाइन किया जा सकता है. जैसे, इस तरह.
val rock = decoration.rock
val wood = decoration.wood
val diver = decoration.diver
इसके बजाय, हर प्रॉपर्टी के लिए एक वैरिएबल बनाया जा सकता है. साथ ही, डेटा ऑब्जेक्ट को वैरिएबल के ग्रुप को असाइन किया जा सकता है. Kotlin, प्रॉपर्टी की वैल्यू को हर वैरिएबल में डालता है.
val (rock, wood, diver) = decoration
इसे डीस्ट्रक्चरिंग कहा जाता है. यह एक उपयोगी शॉर्टहैंड है. वैरिएबल की संख्या, प्रॉपर्टी की संख्या से मेल खानी चाहिए. साथ ही, वैरिएबल को उसी क्रम में असाइन किया जाता है जिस क्रम में उन्हें क्लास में शामिल किया गया है. यहां एक पूरा उदाहरण दिया गया है, जिसे Decoration.kt में आज़माया जा सकता है.
// Here is a data class with 3 properties.
data class Decoration2(val rocks: String, val wood: String, val diver: String){
}
fun makeDecorations() {
val d5 = Decoration2("crystal", "wood", "diver")
println(d5)
// Assign all properties to variables.
val (rock, wood, diver) = d5
println(rock)
println(wood)
println(diver)
}
⇒ Decoration2(rocks=crystal, wood=wood, diver=diver) crystal wood diver
अगर आपको एक या उससे ज़्यादा प्रॉपर्टी की ज़रूरत नहीं है, तो उन्हें छोड़ा जा सकता है. इसके लिए, वैरिएबल के नाम की जगह _
का इस्तेमाल करें. ऐसा नीचे दिए गए कोड में दिखाया गया है.
val (rock, _, diver) = d5
इस टास्क में, आपको Kotlin में मौजूद कुछ खास क्लास के बारे में जानकारी मिलेगी. इनमें ये शामिल हैं:
- सिंगलटन क्लास
- Enums
- सील की गई क्लास
पहला चरण: सिंगलटन क्लास को याद करना
GoldColor
क्लास का इस्तेमाल करके बनाए गए पिछले उदाहरण को याद करें.
object GoldColor : FishColor {
override val color = "gold"
}
GoldColor
का हर इंस्टेंस एक ही काम करता है. इसलिए, इसे class
के बजाय object
के तौर पर एलान किया जाता है, ताकि इसे सिंगलटन बनाया जा सके. इसका सिर्फ़ एक इंस्टेंस हो सकता है.
दूसरा चरण: कोई enum बनाना
Kotlin में एनम भी काम करते हैं. इनकी मदद से, किसी चीज़ को गिना जा सकता है और उसे नाम से रेफ़र किया जा सकता है. यह सुविधा, अन्य भाषाओं में भी उपलब्ध है. डिक्लेरेशन से पहले enum
कीवर्ड लगाकर, किसी enum को डिक्लेयर करें. बेसिक enum के एलान के लिए, सिर्फ़ नामों की सूची की ज़रूरत होती है. हालांकि, हर नाम से जुड़े एक या उससे ज़्यादा फ़ील्ड भी तय किए जा सकते हैं.
- Decoration.kt में, किसी enum का उदाहरण आज़माएं.
enum class Color(val rgb: Int) {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
}
एनम, सिंगलटन की तरह होते हैं. इनमें सिर्फ़ एक वैल्यू हो सकती है. साथ ही, हर वैल्यू के लिए सिर्फ़ एक एनम हो सकता है. उदाहरण के लिए, सिर्फ़ एक Color.RED
, एक Color.GREEN
, और एक Color.BLUE
हो सकता है. इस उदाहरण में, रंग के कॉम्पोनेंट दिखाने के लिए, आरजीबी वैल्यू को rgb
प्रॉपर्टी असाइन किया गया है. ordinal
प्रॉपर्टी का इस्तेमाल करके, किसी enum की ऑर्डिनल वैल्यू भी पाई जा सकती है. साथ ही, name
प्रॉपर्टी का इस्तेमाल करके, उसका नाम भी पाया जा सकता है.
- एनम का कोई दूसरा उदाहरण आज़माएं.
enum class Direction(val degrees: Int) {
NORTH(0), SOUTH(180), EAST(90), WEST(270)
}
fun main() {
println(Direction.EAST.name)
println(Direction.EAST.ordinal)
println(Direction.EAST.degrees)
}
⇒ EAST 2 90
तीसरा चरण: सील की गई क्लास बनाना
सील्ड क्लास ऐसी क्लास होती है जिसे सबक्लास किया जा सकता है. हालांकि, ऐसा सिर्फ़ उस फ़ाइल में किया जा सकता है जिसमें इसे डिक्लेयर किया गया है. अगर किसी दूसरी फ़ाइल में क्लास को सबक्लास करने की कोशिश की जाती है, तो आपको गड़बड़ी का मैसेज मिलेगा.
क्लास और सब-क्लास एक ही फ़ाइल में हैं. इसलिए, Kotlin को सभी सब-क्लास के बारे में स्टैटिक तौर पर पता चल जाएगा. इसका मतलब है कि कंपाइल टाइम पर, कंपाइलर सभी क्लास और सबक्लास को देखता है और उसे पता होता है कि ये सभी क्लास और सबक्लास हैं. इसलिए, कंपाइलर आपके लिए अतिरिक्त जांच कर सकता है.
- AquariumFish.kt में, सील की गई क्लास का एक उदाहरण आज़माएं. इसमें पानी में रहने वाले जीवों के बारे में बताया गया है.
sealed class Seal
class SeaLion : Seal()
class Walrus : Seal()
fun matchSeal(seal: Seal): String {
return when(seal) {
is Walrus -> "walrus"
is SeaLion -> "sea lion"
}
}
Seal
क्लास को किसी दूसरी फ़ाइल में सबक्लास नहीं किया जा सकता. अगर आपको और Seal
टाइप जोड़ने हैं, तो आपको उन्हें उसी फ़ाइल में जोड़ना होगा. इससे सील की गई क्लास, तय संख्या में टाइप दिखाने का एक सुरक्षित तरीका बन जाती हैं. उदाहरण के लिए, सील की गई क्लास, नेटवर्क एपीआई से सफलता या गड़बड़ी की जानकारी वापस पाने के लिए बेहतरीन होती हैं.
इस लेसन में कई विषयों को शामिल किया गया है. ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग की अन्य भाषाओं की तरह ही, Kotlin में भी कई सुविधाएं उपलब्ध हैं. हालांकि, Kotlin में कुछ ऐसी सुविधाएं भी हैं जिनकी मदद से कोड को छोटा और आसानी से समझा जा सकता है.
क्लास और कंस्ट्रक्टर
class
का इस्तेमाल करके, Kotlin में किसी क्लास को परिभाषित करें.- Kotlin, प्रॉपर्टी के लिए सेटर और गैटर अपने-आप बनाता है.
- मुख्य कंस्ट्रक्टर को सीधे तौर पर क्लास की परिभाषा में तय करें. उदाहरण के लिए:
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40)
- अगर मुख्य कंस्ट्रक्टर को अतिरिक्त कोड की ज़रूरत है, तो उसे एक या उससे ज़्यादा
init
ब्लॉक में लिखें. - कोई क्लास,
constructor
का इस्तेमाल करके एक या उससे ज़्यादा सेकंडरी कंस्ट्रक्टर तय कर सकती है. हालांकि, Kotlin के स्टाइल गाइड के मुताबिक, फ़ैक्ट्री फ़ंक्शन का इस्तेमाल करना बेहतर होता है.
विज़िबिलिटी मॉडिफ़ायर और सबक्लास
- Kotlin में सभी क्लास और फ़ंक्शन डिफ़ॉल्ट रूप से
public
होते हैं. हालांकि, मॉडिफ़ायर का इस्तेमाल करके, विज़िबिलिटी कोinternal
,private
याprotected
में बदला जा सकता है. - सबक्लास बनाने के लिए, पैरंट क्लास को
open
के तौर पर मार्क किया जाना चाहिए. - किसी सबक्लास में मेथड और प्रॉपर्टी को ओवरराइड करने के लिए, पैरंट क्लास में मेथड और प्रॉपर्टी को
open
के तौर पर मार्क किया जाना चाहिए. - किसी सील की गई क्लास को सिर्फ़ उसी फ़ाइल में सबक्लास किया जा सकता है जिसमें उसे तय किया गया है.
sealed
प्रीफ़िक्स का इस्तेमाल करके, सील की गई क्लास बनाएं.
डेटा क्लास, सिंगलटन, और enum
- डेटा क्लास बनाने के लिए, एलान से पहले
data
जोड़ें. - डीस्ट्रक्चरिंग,
data
ऑब्जेक्ट की प्रॉपर्टी को अलग-अलग वैरिएबल असाइन करने का एक छोटा तरीका है. class
के बजायobject
का इस्तेमाल करके, सिंगलटन क्लास बनाएं.enum class
का इस्तेमाल करके, enum को तय करें.
ऐब्स्ट्रैक्ट क्लास, इंटरफ़ेस, और डेलिगेशन
- ऐब्स्ट्रैक्ट क्लास और इंटरफ़ेस, क्लास के बीच सामान्य व्यवहार शेयर करने के दो तरीके हैं.
- ऐब्स्ट्रैक्ट क्लास, प्रॉपर्टी और व्यवहार को तय करती है. हालांकि, यह सब-क्लास को लागू करने के लिए छोड़ देती है.
- इंटरफ़ेस, व्यवहार को तय करता है. साथ ही, यह कुछ या सभी व्यवहारों के लिए डिफ़ॉल्ट तौर पर लागू होने वाली सेटिंग दे सकता है.
- किसी क्लास को कंपोज़ करने के लिए इंटरफ़ेस का इस्तेमाल करने पर, क्लास में मौजूद क्लास इंस्टेंस की मदद से क्लास की सुविधाओं को बढ़ाया जाता है.
- इंटरफ़ेस डेलिगेशन में कंपोज़िशन का इस्तेमाल किया जाता है. हालांकि, यह इंटरफ़ेस क्लास को भी लागू करने का अधिकार देता है.
- कंपोज़िशन, इंटरफ़ेस डेलिगेशन का इस्तेमाल करके किसी क्लास में फ़ंक्शन जोड़ने का एक बेहतरीन तरीका है. आम तौर पर, कंपोज़िशन को प्राथमिकता दी जाती है. हालांकि, कुछ समस्याओं के लिए ऐब्स्ट्रैक्ट क्लास से इनहेरिटेंस बेहतर होता है.
Kotlin का दस्तावेज़
अगर आपको इस कोर्स के किसी विषय के बारे में ज़्यादा जानकारी चाहिए या आपको कोई समस्या आ रही है, तो https://kotlinlang.org पर जाएं.
- क्लास और इनहेरिटेंस
- कंस्ट्रक्टर
- फ़ैक्ट्री फ़ंक्शन
- प्रॉपर्टी और फ़ील्ड
- विज़िबिलिटी मॉडिफ़ायर
- ऐब्स्ट्रैक्ट क्लास
- इंटरफ़ेस
- डेलिगेशन
- डेटा क्लास
- Equality
- Destructuring
- ऑब्जेक्ट के एलान
- Enum क्लास
- सीलबंद क्लास
- Kotlin की सील की गई क्लास का इस्तेमाल करके, वैकल्पिक गड़बड़ियों को ठीक करना
Kotlin के ट्यूटोरियल
https://try.kotlinlang.org वेबसाइट पर, Kotlin Koans नाम के रिच ट्यूटोरियल, वेब पर आधारित इंटरप्रेटर, और उदाहरणों के साथ रेफ़रंस दस्तावेज़ों का पूरा सेट शामिल है.
Udacity कोर्स
इस विषय पर Udacity का कोर्स देखने के लिए, Kotlin Bootcamp for Programmers पर जाएं.
IntelliJ IDEA
IntelliJ IDEA के लिए दस्तावेज़, JetBrains की वेबसाइट पर उपलब्ध हैं.
इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.
अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.
इन सवालों के जवाब दें
पहला सवाल
क्लास में एक खास तरीका होता है. यह तरीका, उस क्लास के ऑब्जेक्ट बनाने के लिए ब्लूप्रिंट के तौर पर काम करता है. इस तरीके को क्या कहा जाता है?
▢ बिल्डर
▢ इंस्टैंशिएट करने वाला
▢ कंस्ट्रक्टर
▢ ब्लूप्रिंट
दूसरा सवाल
इंटरफ़ेस और ऐब्स्ट्रैक्ट क्लास के बारे में इनमें से कौनसा स्टेटमेंट सही नहीं है?
▢ ऐब्स्ट्रैक्ट क्लास में कंस्ट्रक्टर हो सकते हैं.
▢ इंटरफ़ेस में कंस्ट्रक्टर नहीं हो सकते.
▢ इंटरफ़ेस और ऐब्स्ट्रैक्ट क्लास को सीधे तौर पर इंस्टैंशिएट किया जा सकता है.
▢ ऐब्स्ट्रैक्ट प्रॉपर्टी को ऐब्स्ट्रैक्ट क्लास की सब-क्लास से लागू किया जाना चाहिए.
तीसरा सवाल
इनमें से कौनसा, Kotlin में प्रॉपर्टी, तरीकों वगैरह के लिए विज़िबिलिटी मॉडिफ़ायर नहीं है?
▢ internal
▢ nosubclass
▢ protected
▢ private
चौथा सवाल
इस डेटा क्लास पर विचार करें:data class Fish(val name: String, val species:String, val colors:String)
इनमें से कौनसा कोड, Fish
ऑब्जेक्ट बनाने और उसे डिस्ट्रक्चर करने के लिए मान्य नहीं है?
▢ val (name1, species1, colors1) = Fish("Pat", "Plecostomus", "gold")
▢ val (name2, _, colors2) = Fish("Bitey", "shark", "gray")
▢ val (name3, species3, _) = Fish("Amy", "angelfish", "blue and black stripes")
▢ val (name4, species4, colors4) = Fish("Harry", "halibut")
पांचवां सवाल
मान लें कि आपके पास एक चिड़ियाघर है, जिसमें कई जानवर हैं और उन सभी की देखभाल करनी है. इनमें से कौनसी चीज़, देखभाल करने के सिद्धांत को लागू करने का हिस्सा नहीं होगी?
▢ जानवरों के खाने के अलग-अलग तरह के भोजन के लिए interface
.
▢ एक abstract Caretaker
क्लास, जिससे अलग-अलग तरह के केयरटेकर बनाए जा सकते हैं.
▢ किसी जानवर को साफ़ पानी देने के लिए interface
.
▢ फ़ीडिंग शेड्यूल में एंट्री के लिए data
क्लास.
अगले लेसन पर जाएं:
कोर्स की खास जानकारी और अन्य कोडलैब के लिंक देखने के लिए, "प्रोग्रामर के लिए Kotlin बूटकैंप: कोर्स में आपका स्वागत है." लेख पढ़ें