Interface در کاتلین — آموزش اینترفیس و پیاده سازی آن + کد

۳۳۳ بازدید
آخرین به‌روزرسانی: ۲۱ دی ۱۴۰۱
زمان مطالعه: ۹ دقیقه
Interface در کاتلین — آموزش اینترفیس و پیاده سازی آن + کد

اینترفیس موجودیت مهمی در برنامه‌نویسی شی‌گرا است که می‌تواند شامل تعریف «متُدهای» (Method) انتزاعی و پیاده‌سازی متد‌های غیر‌انتزاعی باشد. قابلیت استفاده از Interface در کاتلین امکانات بیشتری را در کار با کلاس‌ها در اختیار برنامه‌نویس قرار می‌دهد که از جمله آن‌ها پیاده‌سازی وراثت چندگانه است. در این نوشته ابتدا مفهوم اینترفیس در کاتلین به بیان ساده توضیح داده می‌شود و سپس برای درک بهتر این مفهوم کاربردی، تفاوت‌ بین کلاس و Interface در کاتلین بیان شده است. در ادامه نیز به کمک مثال‌هایی نحوه پیاده‌سازی اینترفیس در کاتلین توضیح داده می‌شود. همچنین در این نوشتار به موارد مهمی همچون ويژگی‌های اینترفیس، پیاده‌سازی چندگانه Interface در کاتلین و وراثت در اینترفیس‌ها پرداخته شده است.

مفهوم Interface در کاتلین چیست؟

اینترفیس‌ها انواع سفارشی ارائه شده توسط کاتلین هستند که امکان نمونه‌سازی مستقیم آن‌ها وجود ندارد. در عوض، اینترفیس‌ها شکلی از رفتار را تعریف می‌کنند که اجرا کننده‌ باید از آن‌ها پیروی کند. با کمک اینترفیس‌ها می‌توان آرایه‌هایی داشت که از ماهیت «اشیا» (Object) داخل خود خبر ندارند. این آرایه‌ها صرفاً می‌دانند که اشیا ذخیره شده چه کار‌هایی می‌توانند انجام دهند.

دلیل استفاده از اینترفیس در کاتلین

اینترفیس در برنامه‌نویسی شی‌گرا، ساختاری است که کامپیوتر را وادار می‌کند تا خصوصیت‌هایی را به یک شی اختصاص دهد. برای نمونه تصور کنید یک کلاس به نام Cat برای ساختن موجودیت گربه و یک کلاس به نام Cow برای ساخت موجودیت گاو و کلاس دیگری به نام Dog برای ساختن موجودیت سگ وجود داشته باشد.

در کلاس‌های بالا عمل صحبت کردن را در نظر بگیرید. برای پیاده‌سازی این فرآیند باید برای هر کدام کلاسی وجود داشته باشد اما به کمک اینترفیس می‌توان یک متد با نام Speak برای هر سه موجودیت پیاده‌سازی کرد. به بیان ساده استفاده از اینترفیس در کاتلین باعث کاهش حجم کدنویسی و در نتیجه صرفه‌جویی در زمان می‌شود.

دلیل استفاده از اینترفیس در کاتلین

تفاوت کلاس و اینترفیس در کاتلین چیست؟

مفهوم Interface در کاتلین می‌تواند شامل «اعلان» (Declare) متد‌های انتزاعی و پیاده‌سازی آن‌ها باشد. اینترفیس در کاتلین امکان ذخیره‌سازی وضعیت را ندارد و همین مورد باعث تمایز میان اینترفیس و کلاس انتزاعی (Abstract Class) شده است. اینترفیس‌ها می‌توانند ویژگی‌هایی نیز داشته باشند اما باید انتزاعی باشند یا امکان پیاده‌سازی دسترسی را فراهم کنند.

چگونه یک Interface در کاتلین ایجاد کنیم؟

پیاده‌سازی اینترفیس در کاتلین با کلمه کلیدی Interface آغاز می‌شود و به دنبال آن، نام اینترفیس مورد نظر قرار داده می‌شود. در ادامه نیز اعضای اینترفیس درون کروشه باز و بسته قرار می‌گیرند. ویژگی مهمی که در اینترفیس‌ها وجود دارد این است که اعضا هیچ تعریفی از خود ندارند، این تعاریف توسط انواع منطبق (Conforming Types) ارائه می‌شود.

تفاوت کلاس و اینترفیس در کاتلین

روش پیاده سازی اینترفیس در کاتلین

Interface در کاتلین را به کمک کلاس یا شی می‌توان پیاده‌ سازی کرد. در زمان پیاده‌سازی اینترفیس، نوع منطبق باید تعریف را برای همه اعضای آن ارائه دهد. برای پیاده‌سازی اینترفیس، نام نوع سفارشی با یک دو نقطه و سپس نام اینترفیس مورد نظر قرار داده می‌شود. در ادامه پیاده‌سازی ساده‌ای از Interface در کاتلین آورده شده است.

1interface Vehicle() { 
2fun start() 
3fun stop() 
4}

بعد از ایجاد اینترفیس در کاتلین برای پیاده‌سازی و استفاده از آن در کلاس به صورت زیر باید عمل کرد.

1class Car: Vehicle

مثالی برای نشان دادن پیاده سازی Interface در کاتلین

در ادامه مثالی برای نمایش نحوه پیاده سازی Interface در کاتلین ارائه شده است.

1interface Vehicle {
2	fun start()
3	fun stop()
4}
5
6class Car : Vehicle {
7	override fun start()
8	{
9		println("Car started")
10	}
11
12	override fun stop()
13	{
14		println("Car stopped")
15	}
16}
17
18fun main()
19{
20	val obj = Car()
21	obj.start()
22	obj.stop()
23}

در ادامه خروجی نمونه‌کد بالا آورده شده است:

Car started
Car stopped

در برنامه فوق، اینترفیس Vehicle  دو متد start()  و stop()  را اعلان می‌کند که باید بازنویسی شوند. کلاس Car  اینترفیس را با استفاده از سینتکس (قواعد نحوی) کلاس پیاده‌سازی می‌کند و با کلمه کلیدی override  دو متد مورد نظر را بازنویسی می‌شوند. در نهایت، تابع main  یک شی از کلاس Car  ایجاد و دو متد مورد نظر را فراخوانی می‌کند.

اینترفیس در کاتلین با پیاده سازی پیش فرض

Interface در کاتلین می‌تواند پیاده‌سازی‌های پیش‌فرض برای توابع داشته باشد. در کد زیر، اینترفیس MyInterface  با پیاده‌سازی پیش‌فرض تابع withImplementation  همراه است.

1interface MyInterface {
2    fun withImplementation() {
3        print("withImplementation() was called")
4    }
5}

در نتیجه کلاس‌هایی که چنین اینترفیس‌هایی را پیاده‌سازی می‌کنند، این امکان را دارند تا از توابع موجود در Interface بدون پیاده‌ سازی مجدد استفاده کنند.

1class MyClass: MyInterface {
2    // No need to reimplement here
3}
4    val instance = MyClass()
5    instance.withImplementation()

در کد فوق، کلاس MyClass  بدون نیاز به پیاده‌سازی مجدد امکان استفاده از تابع پیش‌فرض withImplementation  را دارد.

معرفی فیلم های آموزش برنامه‌ نویسی اندروید

فیلم های اموزش برنامه نویسی اندروید

زبان برنامه‌نویسی کاتلین (Kotlin Programming Language) در حال حاضر به عنوان یکی از محبوب‌ترین زبان‌ها در میان جامعه توسعه‌دهندگان نرم‌افزارهای کاربردی موبایل شناخته می‌شود. همچنین جامعه توسعه‌دهندگان آن به سرعت در حال افزایش است. در سال ۲۰۱۷ میلادی (1396 شمسی)، گوگل، کاتلین را به عنوان دومین زبان رسمی برای توسعه اندروید معرفی کرد. از آن زمان تاکنون، رشد بسیار بزرگ و مهمی در تقاضا برای این زبان برنامه‌نویسی در میان توسعه‌دهندگان و جوامع کسب و کار به وقوع پیوسته است. گوگل در حال حاضر زبان برنامه نویسی کاتلین را به عنوان یکی از بهترین زبان‌های برنامه‌نویسی برای توسعه اپلیکیشن‌های اندرویدی اعلام کرده است. این نشان می‌دهد که آینده خوبی در انتظار این زبان برنامه‌نویسی است.

در پلتفرم فرادرس، دوره‌های آموزشی مرتبط با زبان برنامه نویسی کاتلین در مجموعه آموزش‌های اندروید قابل دسترسی هستند. دوره‌های آموزش زبان برنامه‌نویسی کاتلین در این مجموعه به صورت پروژه‌محور و موضوعی قرار داده شده‌اند. علاوه بر این، دوره‌هایی نیز برای یادگیری برنامه‌نویسی اندروید در این مجموعه وجود دارد. در تصویر بالا تنها تعداد کمی از دوره‌های موجود در این مجموعه آموزشی به‌عنوان نمونه آمده‌اند.

  • برای شروع یادگیری برنامه‌نویسی کاتلین و دسترسی به همه دوره‌های آموزش اندروید + اینجا کلیک کنید.

مقادیر و متد‌های پیش‌فرض در اینترفیس کاتلین

متد‌ها در اینترفیس می‌توانند مقادیر پیش‌فرضی برای پارامتر‌های خود داشته باشند. اگر مقدار پارامتر در زمان فراخوانی تابع ارائه نشده باشد، از مقدار پیش‌فرض آن استفاده می‌شود. همچنین متد‌ها نیز می‌توانند پیاده‌سازی‌های پیش‌فرض داشته باشند. از این حالت در مواردی استفاده می‌شود که متد بازنویسی نشده باشد.

مثالی از کاربرد مقادیر و متد‌های پیش‌فرض در اینترفیس کاتلین

در ادامه مثالی برای نشان دادن مقادیر و متد‌های پیش‌فرض آورده شده است.

1interface FirstInterface {
2	fun add(a: Int, b: Int = 5)
3	fun print()
4	{
5		println("This is a default method defined in the interface")
6	}
7}
8class InterfaceDemo : FirstInterface {
9	override fun add(a: Int, b: Int)
10	{
11		val x = a + b
12		println("Sum is $x")
13	}
14
15	override fun print()
16	{
17		super.print()
18		println("It has been overridden")
19	}
20}
21
22fun main()
23{
24	val obj = InterfaceDemo()
25	println(obj.add(5))
26	obj.print()
27}

خروجی نمونه کد بالا در زیر آورده شده است.

Sum is 10
This is a default method defined in the interface
It has been overridden

در برنامه فوق، اینترفیس FirstInterface  دو متد add()  و print()  را تعریف می‌کند. متد add()  دارای دو پارامتر است که یکی از آن‌ها دارای مقدار پیش‌فرض 5 است. همچنین متد print()  نیز به صورت پیش‌فرض پیاده‌سازی شده است. بنابراین، وقتی کلاس InterfaceDemo  اینترفیس را پیاده‌سازی می‌کند، هر دو متد را بازنویسی می‌کند و اجرای پیش‌فرض print()  را با کلمه کلیدی super  فراخوانی می‌کند. همچنین در تابع main  در زمان فراخوانی متد add()  تنها یک آرگومان مشخص می‌شود، زیرا به آرگومان دوم یک مقدار پیش‌فرض داده شده است.

ویژگی‌های اینترفیس در کاتلین کدامند؟

دقیقا همانند متد‌ها، اینترفیس‌ها نیز می‌توانند دارای ویژگی (Attribute | Property) باشند. با این حال، از آنجا که اینترفیس حالتی ندارد، امکان نمونه‌سازی آن‌ها وجود ندارد. بنابراین هیچ فیلدی برای نگهداری مقادیر آن‌ها وجود ندارد. در نتیجه، فیلد‌های اینترفیس یا انتزاعی هستند یا به صورت پیاده‌سازی ارائه می‌شوند.

ويژگی های اینترفیس

مثالی برای کاربرد ویژگی‌های Interface در کاتلین

در ادامه نمونه کدی برای تعیین ویژگی‌های اینترفیس در کاتلین و نحوه بازنویسی و استفاده از آن‌ها در کلاس آورده شده است.

1interface InterfaceProperties {
2	val a : Int
3	val b : String
4		get() = "Hello"
5}
6
7class PropertiesDemo : InterfaceProperties {
8	override val a : Int = 5000
9	override val b : String = "Property Overridden"
10}
11
12fun main()
13{
14	val x = PropertiesDemo()
15	println(x.a)
16	println(x.b)
17}

در ادامه خروجی نمونه کد بالا آورده شده است.

5000
Property Overridden

در برنامه فوق، اینترفیس InterfaceProperties  داری دو ویژگی است. ويژگی a  از نوع عدد صحیح است و ویژگی b   از نوع رشته به صورت گیرنده ارائه می‌شود. کلاس PropertiesDemo  که اینترفیس InterfaceProperties  را پیاده‌سازی می‌کند، دو ویژگی مربوط به این اینترفیس را بازنویسی می‌کند و برای آن‌ها مقدار جدیدی در نظر می‌گیرد. در انتها نیز تابع main  شیئی از کلاس را ایجاد می‌کند. شی ایجاد شده با استفاده از علامت نقطه در سینتکس این زبان به Property‌‌-های کلاس دسترسی پیدا می‌کند.

پیاده‌سازی چندگانه Interface در کاتلین

گاهی اوقات در برنامه چندین اینترفیس تابع مشابهی را پیاده‌سازی می‌کنند، یا همه آن‌ها با هم یک یا چند پیاده‌سازی را تعریف می‌کنند. در نتیجه، این نحوه تعریف باعث خطا خواهد شد، به این خاطر که برای کامپایلر برنامه مبهم است که کدام پیاده‌سازی باید استفاده شود. کلاس مشتق شده باید به صورت دستی فراخوانی مناسب را ارائه دهد.

مثالی از پیاده‌سازی چندگانه Interface در کاتلین

در ادامه مثالی برای روشن شدن این موضوع آورده شده است.

1interface A {
2fun notImplemented()
3fun implementedOnlyInA() { print("only A") }
4fun implementedInBoth() { print("both, A") }
5fun implementedInOne() { print("implemented in A") }
6}
7
8interface B {
9fun implementedInBoth() { print("both, B") }
10// only defined
11fun implementedInOne()
12}
13
14class MyClass: A, B {
15override fun notImplemented() { print("Normal implementation") }
16// implementedOnlyInA() can by normally used in instances
17// class needs to define how to use interface functions
18override fun implementedInBoth() {
19super<B>.implementedInBoth()
20super<A>.implementedInBoth()
21}
22	
23// even if there's only one implementation,
24// there multiple definitions
25override fun implementedInOne() {
26super<A>.implementedInOne()
27print("implementedInOne class implementation")
28}
29}

در کد بالا کلاس MyClass  از دو اینترفیس A  و B  مشتق شده است. هر دو اینترفیس دارای تابع مشترکی با نام implementedInBoth()  با خروجی متفاوت هستند. بنابراین، کلاس در زمان استفاده از تابع موجود در هر کدام از اینترفیس‌ها باید با کمک کلمه کلیدی super<A>  یا super<B>  به صورت واضح مشخص کند که از پیاده‌سازی موجود در کدام اینترفیس استفاده می‌کند.

زبان برنامه نویسی کاتلین

وراثت در اینترفیس کاتلین

اینترفیس‌ها در کاتلین می‌توانند سایر اینترفیس‌ها را نیز به ارث ببرند. زمانی که یک اینترفیس از اینترفیس دیگری ارث‌بری می‌کند، این امکان فراهم است تا ويژگی‌ها و متد‌های خود را اضافه کند. در بحث پیاده‌سازی نیز باید برای همه ويژگی‌ها و متد‌ها در هر دو اینترفیس تعریفی ارائه دهد. یک Interface در کاتلین می‌تواند بیش از یک اینترفیس را به ارث ببرد. در کد زیر مثالی برای نشان دادن وراثت در اینترفیس ارائه شده است.

1interface Dimensions {
2	val length : Double
3	val breadth : Double
4}
5
6interface CalculateParameters : Dimensions {
7	fun area()
8	fun perimeter()
9}
10
11class XYZ : CalculateParameters {
12	override val length : Double
13		get() = 10.0
14	override val breadth : Double
15		get()= 15.0
16
17	override fun area()
18	{
19		println("Area is ${length * breadth}")
20	}
21
22	override fun perimeter()
23	{
24		println("Perimeter is ${2*(length+breadth)}")
25	}
26}
27
28fun main()
29{
30	val obj = XYZ()
31	obj.area()
32	obj.perimeter()
33}

در ادامه نیز خروجی کد بالا آورده شده است.

Area is 150.0
Perimeter is 50.0

در برنامه فوق، اینترفیس Dimensions  دو ویژگی طول و عرض را تعریف می‌کند. اینترفیس CalculatedParameters  اینترفیس Dimensions  را به ارث می‌برد و همچنین دو متد area()  و perimeter()  را اضافه می‌کند. کلاس XYZ  نیز اینترفیس CalculatedParameters  را پیاده‌سازی می‌کند و ویژگی‌ها و متد‌های آن را بازنویسی می‌کند که در نهایت در تابع اصلی برنامه فراخوانی می‌شوند.

اینترفیس در کاتلین

وراثت چندگانه اینترفیس در کاتلین

کلاس‌ها در کاتلین از مفهوم وراثت واحد پیروی می‌کنند، یعنی هر کلاس فقط می‌تواند کلاس را به ارث ببرد، اما در مورد اینترفیس‎‌ها در کاتلین یک کلاس از «وراثت چندگانه» (Multiple Inheritance) پشتیبانی می‌کند که در زبان برنامه نویسی کاتلین به عنوان «انطباق چندگانه» (multiple conformance) نیز شناخته می‌شود. در مبحث Interface در کاتلین یک کلاس می‌تواند بیش از یک اینترفیس را پیاده‌سازی کند، مشروط بر اینکه تعریفی برای همه اعضای اینترفیس ارائه کند.

مثالی برای نشان دادن وراثت چندگانه اینترفیس در کاتلین

در این بخش از نوشته نمونه کدی برای تعیین نحوه پیاده‌سازی و کاربرد وراثت چندگانه در Interface در کاتلین آورده شده است.

1interface InterfaceProperties {
2	val a : Int
3	val b : String
4		get() = "Hello"
5}
6
7interface InterfaceMethods {
8	fun description()
9}
10
11class MultipleInterface : InterfaceProperties, InterfaceMethods {
12	override val a : Int
13		get() = 50
14
15	override fun description()
16	{
17		println("Multiple Interfaces implemented")
18	}
19}
20fun main()
21{
22	val obj = MultipleInterface()
23	obj.description()
24}

در ادامه نیز خروجی کد بالا نیز آورده شده است.

Multiple Interfaces implemented

در این برنامه دو اینترفیس InterfaceProperties  و InterfaceMethods  تعریف شده‌اند. این اینترفیس‌ها توسط کلاس MultipleInterface  پیاده‌سازی شده‌اند و سپس متد‌ها در تابع main  فراخوانی می‌شوند.

کلمه کلیدی super در Interface

اگر متد موجود در اینترفیس پیاده‌سازی پیش‌فرض خود را داشته باشد، امکان استفاده از کلیدواژه super برای دسترسی به آن متد وجود دارد.

1interface MyInterface {
2 fun funcOne() {
3     // optional body
4     print("Function with default implementation")
5 }
6}

در نمونه کد بالا متد funcOne()  دارای پیاده‌سازی پیش‌فرض است؛ در نتیجه با استفاده از علامت نقطه در سینتکس این زبان امکان دسترسی به متد اینترفیس وجود دارد. در ادامه نحوه دسترسی به متد مورد نظر با استفاده از کلمه کلیدی super آورده شده است.

super.funcOne()

فواید استفاده از Interface

تا اینجا نکات خوبی در مورد مفهوم، کاربرد و نحوه پیاده‌سازی اینترفیس در کاتلین بیان شد. در ادامه به صورت مختصر مزایای استفاده از قابلیت Interface در کار با کلاس‌های انتزاعی بررسی می‌شود. به‌طور کلی Interface‌‌ها دارای مزایای زیر هستند:

  • با استفاده از اینترفیس کار‌ها بیشتر به صورت انتزاعی انجام می‌شوند و این مورد باعث صرفه‌جویی در زمان توسعه برنامه خواهد شد.
  • برنامه‌نویس این امکان را خواهد داشت که برای هر کلاسی که براساس یک Interface پیاده‌سازی می‌شود، توابع خاص را بنویسد.
  • چندین کلاس که از منظر خصوصیات به هم نزدیک هستند را می‌توان بر پایه یک Interface پیاده‌سازی کرد.
  • یادگیری اینترفیس در کاتلین درک مفاهیم شی‌گرایی در این زبان را آسان‌تر می‌کند.
  • قابلیت وراثت چندگانه در اینترفیس‌ها وجود دارد، درحالی که این موضوع در کلاس‌های انتزاعی وجود ندارد.

جمع‌بندی

در این نوشتار به‌طور جامع پیرامون مبحث مهم و کاربردی اینترفیس در کاتلین بحث شد. به‌طور کلی ساختار اینترفیس در کاتلین و «جاوا» (Java) مشابه است و تفاوت چندانی ندارد. مرز بین دو مفهوم کلاس و Interface بسیار نزدیک به یکدیگر است. در نتیجه، توانایی تشخیص دادن این دو مفهوم از یکدیگر و همچنین آشنا بودن به تفاوت‌ها و کاربرد‌های هر کدام برای هر توسعه‌دهنده‌ای که از زبان برنامه‌نویسی کاتلین استفاده می‌کند، بسیار ضروری است.

در این نوشته سعی شد تا مفهوم اینترفیس در کاتلین به سادگی بیان شود. همچنین با ارائه مثال‌های متنوعی در زمینه‌های مختلف کار با Interface، از وراثت گرفته تا پیاده‌سازی های چندگانه سعی شد تا این مبحث مهم و کاربردی به سادگی درک شود.

بر اساس رای ۱۴ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
geeksforgeeksgeeksforgeeks
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *