این کد لبه بخشی از دوره Kotlin Bootcamp برای برنامه نویسان است. اگر به ترتیب روی کدها کار کنید، بیشترین ارزش را از این دوره خواهید گرفت. بسته به دانش خود، ممکن است بتوانید برخی از بخش ها را مرور کنید. این دوره مختص برنامه نویسانی است که یک زبان شی گرا را می دانند و می خواهند Kotlin را یاد بگیرند.
مقدمه
در این کد لبه، شما یک برنامه Kotlin ایجاد می کنید و با کلاس ها و اشیاء در Kotlin آشنا می شوید. اگر زبان شی گرا دیگری بلد باشید، بیشتر این محتوا برای شما آشنا خواهد بود، اما کاتلین تفاوت های مهمی برای کاهش مقدار کد مورد نیاز برای نوشتن دارد. شما همچنین در مورد کلاس های انتزاعی و تفویض رابط کاربری یاد می گیرید.
به جای ساختن یک برنامه نمونه واحد، درسهای این دوره برای ایجاد دانش شما طراحی شدهاند، اما نیمه مستقل از یکدیگر باشند تا بتوانید بخشهایی را که با آنها آشنا هستید، مرور کنید. برای گره زدن آنها به یکدیگر، بسیاری از نمونه ها از تم آکواریوم استفاده می کنند. و اگر می خواهید داستان کامل آکواریوم را ببینید، دوره Kotlin Bootcamp for Programmers Udacity را بررسی کنید.
آنچه از قبل باید بدانید
- اصول اولیه کاتلین، از جمله انواع، عملگرها و حلقه زدن
- نحو تابع کاتلین
- اصول برنامه نویسی شی گرا
- اصول اولیه یک IDE مانند IntelliJ IDEA یا Android Studio
چیزی که یاد خواهید گرفت
- نحوه ایجاد کلاس ها و دسترسی به خصوصیات در Kotlin
- نحوه ایجاد و استفاده از سازنده کلاس در Kotlin
- نحوه ایجاد یک کلاس فرعی و نحوه عملکرد وراثت
- درباره کلاسهای انتزاعی، رابطها، و تفویض رابط
- نحوه ایجاد و استفاده از کلاس های داده
- نحوه استفاده از کلاس های سینگل، enum و مهر و موم شده
کاری که خواهی کرد
- یک کلاس با خصوصیات ایجاد کنید
- یک سازنده برای یک کلاس ایجاد کنید
- یک زیر کلاس ایجاد کنید
- نمونه هایی از کلاس ها و رابط های انتزاعی را بررسی کنید
- یک کلاس داده ساده ایجاد کنید
- در مورد تکتنها، enums و کلاسهای مهر و موم شده بیاموزید
اصطلاحات برنامه نویسی زیر باید قبلاً برای شما آشنا باشد:
- کلاس ها نقشه هایی برای اشیا هستند. به عنوان مثال، کلاس
Aquariumطرح اولیه ساخت یک شی آکواریوم است. - اشیاء نمونه هایی از کلاس ها هستند. یک شی آکواریوم یک
Aquariumواقعی است. - ویژگی ها ویژگی های طبقات هستند، مانند طول، عرض و ارتفاع یک
Aquarium. - متدها که توابع عضو نیز نامیده می شوند، عملکرد کلاس هستند. روشها کارهایی هستند که میتوانید با شی «انجام دهید». به عنوان مثال، می توانید یک شی
AquariumfillWithWater(). - واسط مشخصاتی است که یک کلاس می تواند پیاده سازی کند. به عنوان مثال، تمیز کردن برای اشیاء غیر از آکواریوم رایج است و تمیز کردن عموماً به روش های مشابه برای اشیاء مختلف انجام می شود. بنابراین می توانید یک رابط به نام
Cleanداشته باشید که متدclean()تعریف می کند. کلاسAquariumمی تواند رابطCleanرا برای تمیز کردن آکواریوم با یک اسفنج نرم پیاده سازی کند. - بسته ها راهی برای گروه بندی کدهای مرتبط به منظور سازماندهی نگه داشتن آن یا ایجاد کتابخانه ای از کدها هستند. پس از ایجاد یک بسته، می توانید محتویات بسته را به فایل دیگری وارد کنید و از کد و کلاس های موجود در آن مجددا استفاده کنید.
در این کار، یک بسته جدید و یک کلاس با برخی ویژگی ها و یک متد ایجاد می کنید.
مرحله 1: یک بسته ایجاد کنید
بسته ها می توانند به شما کمک کنند تا کد خود را سازماندهی کنید.
- در قسمت Project ، در زیر پروژه Hello Kotlin ، بر روی پوشه src راست کلیک کنید.
- New > Package را انتخاب کنید و آن را
example.myappبنامید.
مرحله 2: یک کلاس با ویژگی ها ایجاد کنید
کلاس ها با کلمه کلیدی class تعریف می شوند و نام کلاس ها بر اساس قرارداد با یک حرف بزرگ شروع می شود.
- روی بسته example.myapp راست کلیک کنید.
- New > Kotlin File / Class را انتخاب کنید.
- در قسمت Kind ، Class را انتخاب کنید و نام کلاس را
Aquariumبگذارید. IntelliJ IDEA نام بسته را در فایل گنجانده و یک کلاسAquariumخالی برای شما ایجاد می کند. - در داخل کلاس
Aquarium، ویژگی هایvarرا برای عرض، ارتفاع و طول (به سانتی متر) تعریف و مقداردهی اولیه کنید. خواص را با مقادیر پیش فرض مقداردهی کنید.
package example.myapp
class Aquarium {
var width: Int = 20
var height: Int = 40
var length: Int = 100
} در زیر هود، کاتلین به طور خودکار گیرندهها و تنظیمکنندهها را برای ویژگیهایی که در کلاس Aquarium تعریف کردهاید ایجاد میکند، بنابراین میتوانید مستقیماً به ویژگیها دسترسی داشته باشید، برای مثال myAquarium.length .
مرحله 3: یک تابع main() ایجاد کنید
یک فایل جدید به نام main.kt ایجاد کنید تا تابع main() را نگه دارید.
- در قسمت Project در سمت چپ، روی بسته example.myapp راست کلیک کنید.
- New > Kotlin File / Class را انتخاب کنید.
- در زیر منوی کشویی Kind ، انتخاب را به عنوان File نگه دارید و نام فایل را
main.ktبگذارید. IntelliJ IDEA شامل نام بسته است، اما تعریف کلاس برای یک فایل را شامل نمی شود. - یک تابع
buildAquarium()تعریف کنید و در داخل یک نمونه ازAquariumایجاد کنید. برای ایجاد یک نمونه، کلاس را طوری ارجاع دهید که گویی یک تابع است،Aquarium(). این سازنده کلاس را فراخوانی می کند و نمونه ای از کلاسAquariumایجاد می کند، مشابه استفاده ازnewدر زبان های دیگر. - یک تابع
main()تعریف کنید وbuildAquarium()را فراخوانی کنید.
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium()
}
fun main() {
buildAquarium()
}مرحله 4: یک روش اضافه کنید
- در کلاس
Aquarium، روشی برای چاپ مشخصات ابعاد آکواریوم اضافه کنید.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
}- در
main.kt، درbuildAquarium()، متدprintSize()درmyAquariumفراخوانی کنید.
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
در این کار، یک سازنده برای کلاس ایجاد میکنید و کار را با ویژگیها ادامه میدهید.
مرحله 1: یک سازنده ایجاد کنید
در این مرحله یک سازنده به کلاس Aquarium که در اولین وظیفه ایجاد کردید اضافه می کنید. در مثال قبلی، هر نمونه از Aquarium با همان ابعاد ساخته شده است. شما میتوانید بعد از ایجاد آن با تنظیم ویژگیها، ابعاد را تغییر دهید، اما سادهتر است که برای شروع اندازه آن را درست کنید.
در برخی از زبان های برنامه نویسی، سازنده با ایجاد متدی در کلاس که همان نام کلاس را دارد، تعریف می شود. در Kotlin، سازنده را مستقیماً در خود اعلان کلاس تعریف میکنید و پارامترهای داخل پرانتز را طوری مشخص میکنید که گویی کلاس یک متد است. مانند توابع در 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 آنچه را که از مقادیر پیشفرض و پارامترهای نامگذاری شده لازم است ایجاد میکند.
مرحله 2: بلوک های init را اضافه کنید
سازنده های مثال بالا فقط ویژگی ها را اعلام می کنند و مقدار یک عبارت را به آنها اختصاص می دهند. اگر سازنده شما نیاز به کد اولیه بیشتری داشته باشد، می توان آن را در یک یا چند بلوک init قرار داد. در این مرحله چند بلوک init به کلاس Aquarium اضافه می کنید.
- در کلاس
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 به ترتیبی که در تعریف کلاس ظاهر میشوند اجرا میشوند و همه آنها با فراخوانی سازنده اجرا میشوند.
مرحله 3: درباره سازنده های ثانویه بیاموزید
در این مرحله با سازنده های ثانویه آشنا می شوید و یکی را به کلاس خود اضافه می کنید. علاوه بر یک سازنده اولیه، که می تواند یک یا چند بلوک init داشته باشد، یک کلاس Kotlin می تواند یک یا چند سازنده ثانویه نیز داشته باشد تا امکان اضافه بار سازنده را فراهم کند، یعنی سازنده هایی با آرگومان های مختلف.
- در کلاس
Aquariumیک سازنده ثانویه اضافه کنید که با استفاده از کلمه کلیدیconstructor، تعدادی ماهی را به عنوان آرگومان خود در نظر بگیرد. یک خاصیتvaltank برای حجم محاسبه شده آکواریوم بر حسب لیتر بر اساس تعداد ماهی ایجاد کنید. فرض کنید 2 لیتر (2000 سانتی متر 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 را نیز در سازنده اصلی قرار دهید، اما در بیشتر موارد ضروری نیست.
مرحله 4: یک گیرنده ویژگی جدید اضافه کنید
در این مرحله شما یک گیرنده خصوصیت واضح اضافه می کنید. کاتلین به طور خودکار دریافت کننده ها و تنظیم کننده ها را زمانی که ویژگی ها را تعریف می کنید تعریف می کند، اما گاهی اوقات مقدار یک ویژگی نیاز به تنظیم یا محاسبه دارد. به عنوان مثال، در بالا، حجم Aquarium را چاپ کردید. شما می توانید حجم را به عنوان یک ویژگی با تعریف یک متغیر و یک گیرنده برای آن در دسترس قرار دهید. از آنجایی که volume باید محاسبه شود، دریافت کننده باید مقدار محاسبه شده را برگرداند که می توانید با یک تابع یک خطی این کار را انجام دهید.
- در کلاس
Aquariumیک ویژگیIntبه نامvolumeتعریف کنید و یک متد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
ابعاد و حجم مانند قبل است، اما حجم فقط یک بار پس از مقداردهی اولیه شی توسط سازنده اولیه و سازنده ثانویه چاپ می شود.
مرحله 5: یک تنظیم کننده ویژگی اضافه کنید
در این مرحله یک تنظیم کننده ویژگی جدید برای حجم ایجاد می کنید.
- در کلاس
Aquarium،volumeبهvarتغییر دهید تا بتوان آن را بیش از یک بار تنظیم کرد. - با افزودن متد
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 عمومی است، به این معنی که همه چیز در همه جا قابل دسترسی است، از جمله کلاسها، متدها، ویژگیها و متغیرهای عضو.
در کاتلین، کلاسها، اشیاء، رابطها، سازندهها، توابع، ویژگیها و تنظیمکنندههای آنها میتوانند اصلاحکنندههای دید داشته باشند:
-
publicیعنی خارج از کلاس قابل مشاهده است. همه چیز به طور پیش فرض عمومی است، از جمله متغیرها و متدهای کلاس. -
internalبه این معنی است که فقط در آن ماژول قابل مشاهده خواهد بود. ماژول مجموعهای از فایلهای Kotlin است که با هم کامپایل شدهاند، برای مثال، یک کتابخانه یا برنامه. -
privateبه این معنی است که فقط در آن کلاس (یا فایل منبع در صورتی که با توابع کار می کنید) قابل مشاهده است. -
protectedهمانprivateاست، اما برای هر زیر کلاسی نیز قابل مشاهده خواهد بود.
برای اطلاعات بیشتر به Visibility Modifiers در مستندات Kotlin مراجعه کنید.
متغیرهای عضو
ویژگی های یک کلاس یا متغیرهای عضو به طور پیش فرض public هستند. اگر آنها را با var تعریف کنید، قابل تغییر هستند، یعنی قابل خواندن و نوشتن هستند. اگر آنها را با val تعریف کنید، پس از مقداردهی اولیه فقط خواندنی هستند.
اگر خصوصیتی را میخواهید که کد شما بتواند بخواند یا بنویسد، اما کد خارجی فقط بتواند بخواند، میتوانید ویژگی و گیرنده آن را عمومی بگذارید و تنظیم کننده را خصوصی اعلام کنید، مانند شکل زیر.
var volume: Int
get() = width * height * length / 1000
private set(value) {
height = (value * 1000) / (width * length)
}در این کار، یاد می گیرید که چگونه کلاس های فرعی و ارث بری در Kotlin کار می کنند. آنها شبیه به آنچه در زبان های دیگر دیده اید هستند، اما تفاوت هایی وجود دارد.
در کاتلین، به طور پیش فرض، کلاس ها را نمی توان زیر کلاسه کرد. به طور مشابه، ویژگیها و متغیرهای عضو نمیتوانند توسط زیر کلاسها لغو شوند (اگرچه میتوان به آنها دسترسی داشت).
شما باید یک کلاس را به عنوان open علامت گذاری کنید تا اجازه دهید کلاس فرعی باشد. به طور مشابه، شما باید ویژگیها و متغیرهای عضو را بهعنوان open علامتگذاری کنید تا آنها را در زیر کلاس لغو کنید. برای جلوگیری از لو رفتن تصادفی جزئیات پیاده سازی به عنوان بخشی از رابط کلاس، کلمه کلیدی open مورد نیاز است.
مرحله 1: کلاس آکواریوم را باز کنید
در این مرحله کلاس 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باز با مقدار"rectangle"اضافه کنید.
open val shape = "rectangle"- یک خاصیت
waterآزاد را با یک گیرنده اضافه کنید که 90 درصد حجمAquariumرا برمی گرداند.
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()کد را تغییر دهید تا یکAquariumباwidth = 25،length = 25وheight = 40ایجاد کنید.
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)
مرحله 2: یک زیر کلاس ایجاد کنید
- یک زیر کلاس از
Aquariumبه نامTowerTankایجاد کنید که یک مخزن استوانه ای گرد را به جای مخزن مستطیلی اجرا می کند. میتوانیدTowerTankزیرAquariumاضافه کنید، زیرا میتوانید کلاس دیگری را در همان فایل کلاسAquariumاضافه کنید. - در
TowerTank، ویژگیheightرا که در سازنده تعریف شده است، لغو کنید. برای لغو یک ویژگی، از کلمه کلیدیoverrideدر زیر کلاس استفاده کنید.
- سازنده
TowerTankراdiameterدرآورید. هنگام فراخوانی سازنده در سوپرکلاسAquariumdiameterهم برایlengthو همwidthاستفاده کنید.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {- برای محاسبه یک استوانه، خاصیت حجم را نادیده بگیرید. فرمول یک استوانه پی ضربدر شعاع مجذور ارتفاع است. شما باید
PIثابت را ازjava.lang.Mathوارد کنید.
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()یکTowerTankبا قطر 25 سانتی متر و ارتفاع 45 سانتی متر ایجاد کنید. اندازه را چاپ کنید.
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 ایجاد می کنید تا رفتار مشترک همه ماهی ها را تعریف کنید.
- نه یک کلاس انتزاعی و نه یک رابط را نمی توان به تنهایی نمونه سازی کرد، به این معنی که شما نمی توانید اشیایی از آن نوع را مستقیما ایجاد کنید.
- کلاس های انتزاعی سازنده دارند.
- اینترفیس ها نمی توانند هیچ منطق سازنده ای داشته باشند یا هیچ حالتی را ذخیره کنند.
مرحله 1. یک کلاس انتزاعی ایجاد کنید
- در قسمت 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 .

مرحله 2. یک رابط ایجاد کنید
- در AquariumFish.kt ، یک رابط به نام
FishActionبا متدeat()ایجاد کنید.
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 تشکیل شده و پیاده سازی شده اند.

زمان استفاده از کلاس های انتزاعی در مقابل رابط ها
مثالهای بالا ساده هستند، اما وقتی کلاسهای مرتبط زیادی دارید، کلاسهای انتزاعی و رابطها میتوانند به شما کمک کنند طراحی خود را تمیزتر، سازماندهیتر و نگهداری راحتتر داشته باشید.
همانطور که در بالا ذکر شد، کلاس های انتزاعی می توانند سازنده داشته باشند، و رابط ها نمی توانند، اما در غیر این صورت بسیار شبیه هستند. بنابراین، چه زمانی باید از هر کدام استفاده کنید؟
هنگامی که از واسط ها برای نوشتن یک کلاس استفاده می کنید، عملکرد کلاس از طریق نمونه های کلاسی که در آن وجود دارد، گسترش می یابد. ترکیب تمایل دارد استفاده مجدد و استدلال کد را آسان تر از ارث بری از یک کلاس انتزاعی کند. همچنین، میتوانید از چندین رابط در یک کلاس استفاده کنید، اما فقط میتوانید از یک کلاس انتزاعی زیر کلاسبندی کنید.
ترکیب اغلب منجر به کپسوله سازی بهتر، اتصال کمتر (وابستگی متقابل)، رابط های تمیزتر و کدهای قابل استفاده بیشتر می شود. به این دلایل، استفاده از ترکیب با رابط ها طراحی ارجح است. از سوی دیگر، به ارث بردن از یک طبقه انتزاعی تمایل دارد برای برخی از مشکلات مناسب باشد. بنابراین شما باید ترکیب را ترجیح دهید، اما زمانی که وراثت منطقی است، کاتلین به شما اجازه می دهد این کار را نیز انجام دهید!
- اگر روشهای زیادی دارید و یک یا دو پیادهسازی پیشفرض دارید، برای مثال مانند
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")
} کار قبلی کلاس های انتزاعی، رابط ها و ایده ترکیب بندی را معرفی کرد. تفویض رابط یک تکنیک پیشرفته است که در آن متدهای یک رابط توسط یک شی کمک کننده (یا نماینده) پیاده سازی می شوند که سپس توسط یک کلاس استفاده می شود. این تکنیک زمانی میتواند مفید باشد که از یک رابط در یک سری کلاسهای غیرمرتبط استفاده میکنید: عملکرد رابط مورد نیاز را به یک کلاس کمکی جداگانه اضافه میکنید و هر یک از کلاسها از نمونهای از کلاس کمکی برای پیادهسازی عملکرد استفاده میکنند.
در این کار، از تفویض رابط برای افزودن قابلیت به یک کلاس استفاده می کنید.
مرحله 1: ایجاد یک رابط جدید
- در AquariumFish.kt ، کلاس
AquariumFishحذف کنید. به جای ارث بردن از کلاسAquariumFish،PlecostomusوSharkقرار است رابط هایی را هم برای اکشن ماهی و هم برای رنگ آنها پیاده سازی کنند. - یک رابط جدید به
FishColorایجاد کنید که رنگ را به عنوان یک رشته تعریف می کند.
interface FishColor {
val color: String
}-
Plecostomusبرای پیاده سازی دو رابط،FishActionوFishColorتغییر دهید. بایدcolorازFishColorنادیده بگیرید وeat()را ازFishAction.
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}- کلاس
Sharkخود را تغییر دهید تا به جای ارث بردن ازAquariumFish، دو رابط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")
}
}مرحله 2: یک کلاس تک تن درست کنید
سپس، با ایجاد یک کلاس کمکی که FishColor را پیادهسازی میکند، تنظیمات بخش delegation را پیادهسازی میکنید. شما یک کلاس پایه به نام GoldColor ایجاد می کنید که FishColor پیاده سازی می کند - تمام کاری که انجام می دهد این است که رنگ آن طلایی است.
ایجاد چندین نمونه از GoldColor منطقی نیست، زیرا همه آنها دقیقاً یک کار را انجام می دهند. بنابراین Kotlin به شما اجازه می دهد کلاسی را اعلام کنید که در آن فقط می توانید یک نمونه از آن را با استفاده از object کلمه کلیدی به جای class ایجاد کنید. کاتلین آن یک نمونه را ایجاد می کند و آن نمونه با نام کلاس ارجاع داده می شود. سپس تمام اشیاء دیگر فقط می توانند از این یک نمونه استفاده کنند—هیچ راهی برای ساختن نمونه های دیگر از این کلاس وجود ندارد. اگر با الگوی سینگلتون آشنا هستید، این روشی است که تکتنهها را در کاتلین پیادهسازی میکنید.
- در AquariumFish.kt یک شی برای
GoldColorایجاد کنید. رنگ را نادیده بگیرید.
object GoldColor : FishColor {
override val color = "gold"
}مرحله 3: اضافه کردن نمایندگی رابط برای FishColor
اکنون برای استفاده از نمایندگی رابط آماده هستید.
- در AquariumFish.kt ، رد
colorرا ازPlecostomusحذف کنید. - کلاس
Plecostomusرا تغییر دهید تا رنگ آن را ازGoldColorدریافت کنید. این کار را با افزودنby GoldColorبه اعلان کلاس و ایجاد نمایندگی انجام می دهید. چیزی که می گوید این است که به جای پیاده سازیFishColorاز پیاده سازی ارائه شده توسطGoldColorاستفاده کنید. بنابراین هر بار که بهcolorدسترسی پیدا می شود، بهGoldColorواگذار می شود.
class Plecostomus: FishAction, FishColor by GoldColor {
override fun eat() {
println("eat algae")
}
}با کلاس همانطور که هست، تمام پلکوها طلایی خواهند شد، اما این ماهی ها در واقع رنگ های زیادی دارند. شما می توانید با افزودن یک پارامتر سازنده برای رنگ با GoldColor به عنوان رنگ پیش فرض برای Plecostomus به این موضوع رسیدگی کنید.
- کلاس
Plecostomusرا تغییر دهید تا درfishColorبا سازنده آن یک پاس داده شود و پیش فرض آن را رویGoldColorقرار دهید. تغییر نمایندگی ازby GoldColorبهby fishColor.
class Plecostomus(fishColor: FishColor = GoldColor): FishAction,
FishColor by fishColor {
override fun eat() {
println("eat algae")
}
}مرحله 4: تفویض اختیار رابط را برای FishAction اضافه کنید
به همین ترتیب، میتوانید از تفویض رابط برای FishAction استفاده کنید.
- در AquariumFish.kt یک کلاس
PrintingFishActionبسازید کهFishActionرا پیادهسازی میکند، که یکString،foodمیگیرد، سپس آنچه را که ماهی میخورد چاپ میکند.
class PrintingFishAction(val food: String) : FishAction {
override fun eat() {
println(food)
}
}- در کلاس
Plecostomus، تابع overrideeat()را حذف کنید، زیرا آن را با یک نمایندگی جایگزین میکنید. - در بیانیه
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 برای کلاسهای داده آشنا میشوید.
مرحله 1: یک کلاس داده ایجاد کنید
- برای نگه داشتن کد جدید، یک
decorبسته جدید را در زیر بسته example.myapp اضافه کنید. روی example.myapp در قسمت Project کلیک راست کرده و File > New > Package را انتخاب کنید. - در بسته، یک کلاس جدید به نام
Decorationایجاد کنید.
package example.myapp.decor
class Decoration {
}- برای تبدیل
Decorationبه یک کلاس داده، پیشوند اعلان کلاس را با کلمه کلیدیdataقرار دهید. - یک ویژگی
Stringبه نامrocksاضافه کنید تا به کلاس مقداری داده بدهید.
data class Decoration(val rocks: String) {
}- در فایل، خارج از کلاس، یک تابع
makeDecorations()برای ایجاد و چاپ نمونه ای از یکDecorationبا"granite"اضافه کنید.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
}- یک تابع
main()برای فراخوانیmakeDecorations()اضافه کنید و برنامه خود را اجرا کنید. به خروجی معقولی که ایجاد می شود توجه کنید زیرا این یک کلاس داده است.
⇒ 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()یک عبارت print اضافه کنید که نتیجه مقایسهdecoration1باdecoration2را چاپ می کند و مورد دوم را کهdecoration3باdecoration2مقایسه می کند. از متد ()quals که توسط کلاس های داده ارائه می شود استفاده کنید.
println (decoration1.equals(decoration2))
println (decoration3.equals(decoration2))- کد خود را اجرا کنید
⇒ Decoration(rocks=granite) Decoration(rocks=slate) Decoration(rocks=slate) false true
مرحله 2. از تخریب استفاده کنید
برای دستیابی به ویژگی های یک شی داده و اختصاص دادن آنها به متغیرها، می توانید آنها را یکی یکی تخصیص دهید، مانند این.
val rock = decoration.rock
val wood = decoration.wood
val diver = decoration.diverدرعوض، میتوانید متغیرهایی را برای هر ویژگی یک متغیر بسازید و شی داده را به گروه متغیرها اختصاص دهید. کاتلین مقدار ویژگی را در هر متغیر قرار می دهد.
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در این کار، با برخی از کلاس های هدف ویژه در کاتلین آشنا می شوید، از جمله موارد زیر:
- کلاس های تک تن
- Enums
- کلاس های مهر و موم شده
مرحله 1: کلاس های تک تن را به یاد بیاورید
مثال قبلی را با کلاس GoldColor به یاد بیاورید.
object GoldColor : FishColor {
override val color = "gold"
}از آنجایی که هر نمونه از GoldColor همان کار را انجام می دهد، به جای اینکه به عنوان یک class ، آن را به عنوان یک تک تن درآورد، به عنوان یک object اعلان می شود. فقط یک نمونه از آن می تواند وجود داشته باشد.
مرحله 2: یک enum ایجاد کنید
Kotlin همچنین از enums پشتیبانی میکند که به شما امکان میدهد چیزی را برشمارید و با نام آن را ارجاع دهید، دقیقاً مانند سایر زبانها. با قرار دادن پیشوند اعلان با کلمه کلیدی enum یک enum را اعلام کنید. یک اعلان اولیه فقط به فهرستی از نام ها نیاز دارد، اما می توانید یک یا چند فیلد مرتبط با هر نام را نیز تعریف کنید.
- در Decoration.kt ، نمونه ای از enum را امتحان کنید.
enum class Color(val rgb: Int) {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
}Enum ها کمی شبیه تک تون ها هستند - از هر مقدار در شمارش فقط یک و فقط یکی می تواند وجود داشته باشد. برای مثال، فقط میتواند یک Color.RED ، یک Color.GREEN و یک Color.BLUE وجود داشته باشد. در این مثال، مقادیر RGB به خاصیت rgb اختصاص داده شده است تا اجزای رنگ را نشان دهد. همچنین می توانید مقدار ترتیبی یک enum را با استفاده از ویژگی ordinal و نام آن را با استفاده از ویژگی name بدست آورید.
- نمونه دیگری از enum را امتحان کنید.
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
مرحله 3: یک کلاس مهر و موم شده ایجاد کنید
یک کلاس مهر و موم شده، کلاسی است که می تواند زیر کلاسه شود، اما فقط در داخل فایلی که در آن اعلام شده است. اگر بخواهید کلاس را در فایل دیگری زیر کلاس بندی کنید، با خطا مواجه می شوید.
از آنجایی که کلاس ها و زیر کلاس ها در یک فایل قرار دارند، کاتلین تمام زیر کلاس ها را به صورت ایستا می شناسد. یعنی در زمان کامپایل، کامپایلر تمام کلاس ها و زیر کلاس ها را می بیند و می داند که این همه آنهاست، بنابراین کامپایلر می تواند بررسی های اضافی را برای شما انجام دهد.
- در 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 بیشتری اضافه کنید، باید آنها را در همان فایل اضافه کنید. این باعث می شود کلاس های مهر و موم شده راهی ایمن برای نشان دادن تعداد ثابتی از انواع باشند. به عنوان مثال، کلاس های مهر و موم شده برای بازگشت موفقیت یا خطا از یک API شبکه عالی هستند.
این درس زمینه های زیادی را پوشش داد. در حالی که بسیاری از آن باید با سایر زبان های برنامه نویسی شی گرا آشنا باشد، کاتلین برخی ویژگی ها را اضافه می کند تا کد را مختصر و خوانا نگه دارد.
کلاس ها و سازنده ها
- با استفاده از
classیک کلاس در 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یک کلاس مهر و موم شده بسازید.
کلاسهای داده، تکتونها و enums
- با قرار دادن پیشوند اعلان با
dataیک کلاس داده بسازید. - Destructuring خلاصه ای برای تخصیص ویژگی های یک شی
dataبه متغیرهای جداگانه است. - با استفاده از
objectبه جایclass، یک کلاس singleton بسازید. - با استفاده از
enum classیک enum تعریف کنید.
کلاس های انتزاعی، رابط ها و تفویض اختیار
- کلاس های انتزاعی و رابط ها دو راه برای به اشتراک گذاشتن رفتار مشترک بین کلاس ها هستند.
- یک کلاس انتزاعی خصوصیات و رفتار را تعریف می کند، اما پیاده سازی را به زیر کلاس ها واگذار می کند.
- یک رابط رفتار را تعریف می کند و ممکن است اجرای پیش فرض را برای برخی یا همه رفتارها ارائه دهد.
- هنگامی که از واسط ها برای نوشتن یک کلاس استفاده می کنید، عملکرد کلاس از طریق نمونه های کلاسی که در آن وجود دارد، گسترش می یابد.
- تفویض رابط از ترکیب استفاده می کند، اما پیاده سازی را به کلاس های رابط نیز واگذار می کند.
- Composition یک راه قدرتمند برای افزودن عملکرد به کلاس با استفاده از تفویض رابط است. به طور کلی ترکیب بندی ترجیح داده می شود، اما ارث بردن از یک کلاس انتزاعی برای برخی از مشکلات مناسب تر است.
مستندات کاتلین
اگر در مورد هر موضوعی در این دوره اطلاعات بیشتری می خواهید، یا اگر گیر کرده اید، https://kotlinlang.org بهترین نقطه شروع شما است.
- طبقات و ارث
- سازندگان
- توابع کارخانه
- خواص و زمینه ها
- اصلاح کننده های دید
- کلاس های انتزاعی
- رابط ها
- هیئت نمایندگی
- کلاس های داده
- برابری
- در حال تخریب
- اعلامیه های اشیاء
- کلاس های Enum
- کلاس های مهر و موم شده
- مدیریت خطاهای اختیاری با استفاده از کلاس های مهر و موم شده Kotlin
آموزش های کوتلین
وب سایت https://try.kotlinlang.org شامل آموزش های غنی به نام Kotlin Koans ، یک مترجم مبتنی بر وب و مجموعه کاملی از مستندات مرجع با مثال است.
دوره udacity
برای مشاهده دوره Udacity در این موضوع ، برای برنامه نویسان به Kotlin Bootcamp مراجعه کنید.
ایده IntelliJ
مستندات ایده IntelliJ را می توان در وب سایت JetBrains یافت.
این بخش، تکالیف احتمالی را برای دانشآموزانی که در این آزمایشگاه کد به عنوان بخشی از دورهای که توسط یک مربی هدایت میشود، کار میکنند، فهرست میکند. این وظیفه مربی است که موارد زیر را انجام دهد:
- در صورت نیاز تکالیف را تعیین کنید.
- نحوه ارسال تکالیف را با دانش آموزان در میان بگذارید.
- تکالیف را نمره دهید.
مربیان میتوانند از این پیشنهادات به اندازهای که میخواهند استفاده کنند، و باید با خیال راحت هر تکلیف دیگری را که فکر میکنند مناسب است، محول کنند.
اگر به تنهایی از طریق این کدها کار می کنید، از این تکالیف برای آزمایش دانش خود استفاده کنید.
به این س questions الات پاسخ دهید
سوال 1
کلاس ها یک روش خاص دارند که به عنوان یک طرح برای ایجاد اشیاء آن کلاس عمل می کند. این روش چیست؟
▢ سازنده
▢ یک فوری
▢ سازنده
▢ یک طرح
سوال 2
کدام یک از گفته های زیر در مورد رابط ها و کلاس های انتزاعی صحیح نیست؟
class کلاسهای انتزاعی می توانند سازنده داشته باشند.
▢ رابط ها نمی توانند سازنده داشته باشند.
▢ رابط ها و کلاس های انتزاعی می توانند مستقیماً فوراً باشند.
properties خصوصیات انتزاعی باید توسط زیر کلاسهای کلاس انتزاعی اجرا شود.
سوال 3
کدام یک از موارد زیر اصلاح کننده قابلیت دید Kotlin برای خواص ، روش ها و غیره نیست؟
▢ internal
▢ nosubclass
▢ protected
▢ private
سوال 4
این کلاس داده را در نظر بگیرید:
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")
سوال 5
بیایید بگوییم شما یک باغ وحش با حیوانات زیادی دارید که همه آنها باید از آنها مراقبت شوند. کدام یک از موارد زیر جزئی از اجرای مراقبت نیست؟
▢ interface برای انواع مختلف غذاهایی که حیوانات می خورند.
class کلاس abstract Caretaker که از آن می توانید انواع مختلفی از سرپرستان را ایجاد کنید.
▢ interface دادن آب تمیز به حیوان.
class کلاس data برای ورود در یک برنامه تغذیه.
به درس بعدی بروید:
برای مرور کلی از این دوره ، از جمله پیوندها به سایر Codelabs ، به "Kotlin Bootcamp برای برنامه نویسان: به دوره خوش آمدید" مراجعه کنید.