افزودن متدها به کلاسی که از پیش تعریف شده است (extend)
اگر شما با زبان سی شارپ آشنا باشید احتمالا با مفهوم extension method آشنا هستید. این متد ها به این شکل هستند که اگر شما حتی به سورس یک کلاس هم دسترسی ندارید می توانید یک متد بنویسید و آن متد را به عنوان عضو کلاس مورد نظر معرفی کنید. در این صورت وقتی که شیئی از کلاس مورد نظر ساخته شود در لیست متدهای عضو آن کلاس متد ها هم وجود دارد و می توانیم آن را فراخوانی کنیم. این امکان در زبان کتلین هم وجود دارد. نحوه تعریف این متدها به گونه ای است که هنگام تعریف متد اسم کلاس هم قبل از آورده می شود و با نام متد با یک نقطه از یکدیگر جدا می شوند. برای مثال می خواهیم با توجه به سن یک شخص تصمیم بگیریم که شخص مورد نظر نوجوان است یا خیر برای این کار از کد زیر استفاده می کنیم. دقت کنید که این کد خارج از کلاس Person نوشته می شود ولی جزء متدهای عضو کلاس Person خواهد بود.
fun Person.isTeenager(): Boolean { return age in 13..19 }در کد بالا اگر age بین 13 تا 19 باشد مقدار true و در غیر این صورت مقدار false برگشت داده خواهد شد. قابلیت extension زمانی کاربردی است که شما می خواهید یک متد را به یک کلاس بچسبانید ولی کد کلاس در دسترس شما نیست. برای مثال کلاس String که یکی از کلاس های جاوا و کتلین می باشد را در نظر بگیرید با استفاده از کد زیر می توان یک متد به آن اضافه کرد که مشخص کند که رشته مورد نظر آیا دارای فاصله خالی هست یا خیر:
fun String.containsSpaces(): Boolean { return this.indexOf(" ")!=-1 }
ارث بری در کلاس ها
ارث بری کلاس ها در کتلین با جاوا تفاوت هایی دارد که باید به آنها دقت داشته باشید.
- به جای کلمه کلیدی extends از علامت : (دو نقطه) استفاده شود.
- برای این که بتوان از یک کلاس ارث بری کرد باید هنگام تعریف کلاس مورد از کلمه کلیدی open استفاده کرد.
- اگر کلاس پدر دارای constructor با ورودی است باید در constructor کلاس فرزند مقادیر پدر را نیز مقدار دهی کنیم.
open class Person(var name: String, var age: Int, var college: String?) { } class Employee(name: String, age: Int, college: String?, var company: String) : Person(name, age, college) { }
Override کردن متد های عضو یک کلاس
در کتلین برای این که بتوانید یک متد را override کنید باید آن را درکلاس پدر به صورت open تعریف کنید و در کلاس فرزند با استفاده از کلمه کلیدی override آن را تعریف کنید. به مثال زیر توجه کنید که در کلاس فرزند تعریف شده است.
override fun isChild(): Boolean { return true }در زبان کتلین نمی توان متد از نوع static تعریف کرد. ولی شما در داخل یک پکیج می توانید متدهایی را تعریف کنید که عضو کلاسی نباشند مانند متد main در مثال زیر در داخل پکیج com.radib یک متد main تعریف شده است:
package com.radib fun main(args:Array<String>) { }
توابع در کتلین
در مطلب قبلی در مورد توابع صحبت کردیم ولی در این مطلب به صورت مفصل تر به آن ها خواهیم پرداخت و امکاناتی که کتلین در این مورد ارائه می کند را توضیح می دهیم.
ساخت توابع تک عبارتی: اگر تابع شما به شکلی است که کل کد بدنه آن یک عبارت است می توان آن را به گونه ساده تری معرفی کرد. به شکلی که جلوی تابع از علامت = استفاده کنیم. برای مثال اگر بخواهیم تعیین کنیم که شخصی پیر است یا خیر می توانیم متد آن را به شکل زیر بنویسیم زیرا که فقط یک عبارت برای این کار لازم است.
fun isOld(): Boolean = age in 70 .. 89
توابع مرتبه بالا(higher order function) و lambda expression
توابع مرتبه بالا توابعی هستند که یا یک یا چند تابع دیگر را به عنوان وردی می گیرند و یا یک تابع را به عنوان خروجی برمی گردانند. Lambda expression را می توان تابعی دانست که نام ندارد. معمولا توابع مرتبه بالاتر را به همراه lambda expression به کار می برند. در کد زیر یک مثال از عبارت لامبدا را می بینید. لطفا به سینتکس آن دقت کنید.
{x, y -> x+y}در مثال بالا عبارت گفته شده دو پارامتر را به عنوان ورودی می گیرد (x, y) و نتیجه جمع آنها را بر می گرداند. شکل این عبارت ها به گونه ای است که پارامتر های قبل از -> قرار می گیرد و عباراتی که بعد از -> قرار میگیرد عملیاتی است که بر روی پارامترها انجام می شود. برای استفاده از عبارات لامبدا باید به شکل زیر در زبان کتلین استفاده می کنیم.
val sumLambda: (Int, Int) -> Int = {x,y -> x+y} val actualSum = sumLambda(3,4)به این نکته دقت داشته باشید که متغیر هایی که عبارات لامبدا را نگهداری می کند نوع پارامتر ها و نوع خروجی آن را مشخص می کند. ساخت یک تابع مرتبه بالاتر یک عبارت لامبدا را می تواند به صورت پارامتر ورودی دریافت کند. برای مثال بالا که یک عبارت لامبدا است که دو عدد را گرفته و یک عدد را به عنوان خروجی برمی گرداند شما باید کد زیر را بنویسید. به نحوه استفاده از عبارت لامبدا و معرفی آن دقت کنید.
fun doubleTheResult(x:Int, y:Int, f:(Int, Int)->Int): Int { return f(x,y) * 2 }برای فراخوانی تابع بالا باید به شکل زیر عمل کنیم:
val result1 = doubleTheResult(3, 4, sumLambda) val result2 = doubleTheResult(3, 4, {x,y -> x+y})اغلب از عبارات لامبدا با آرایه ها استفاده می شود. برای مثال به آرایه زیر که یک آرایه از عدد های صحیح می باشد دقت کنید.
val numbers:Array<Int> = arrayOf(1, 2, 3, 4, 5)حال در نظر بگیرید که می خواهیم برای هر کدام از عدد های آرایه بالا مربع هرکدام را به دست آوریم. برای این کار به آرایه ساخته شده در کد زیر دقت کند که با استفاده از تابع map و عبارت لامبدا دقت کنید.
val squaredNumbers = numbers.map({x -> x * x})نتیجه آرایه دوم 25و16و9و4و1 خواهد بود.