کلاس های ابسترکت (abstract) در کاتلین

کلاس های abstract در کاتلین

توضیحات و ویژگی ها

به کلاس، تابع و پراپرتی های معمولی concrete میگیم اما نوعی از کلاس در کاتلین وجود داره که بهش abstract میگیم و میتونیم داخلش علاوه بر توابع و پراپرتی های concrete، توابع و پراپرتی های abstract نیز تعریف کنیم.

میتونیم یک تابع (متد) رو abstract تعریف کنیم و هنگام ارث بری و بازنویسی تابعو کامل پیاده‌سازی کنیم برای این کار تابع باید در کلاس abstract یا در interface تعریف بشه و هنگام ارث بری بازنویسی بشه، در این مطلب کلاس های ابسترکت رو بررسی میکنیم و در مطلب بعدی به اینترفیس ها می پردازیم.

برای تعریف کلاس ابسترکت از کلیدواژه ی abstract قبل از کلیدواژه ی class استفاده میکنیم و برای تعریف پراپرتی و توابع ابسترکت هم مثل کلاس ابسترکت ابتدا کلیدواژه ی abstract رو مینویسیم.

با اینکه میتونیم در کلاس ابسترکت، کانستراکتور تعریف کنیم اما نمیتونیم مستقیم از این کلاس ها نمونه (شی) سازی کنیم و باید از ساب کلاسی که concrete است نمونه سازی کنیم.

فرم کلی کلاس های ابسترکت:

abstract class MyAbstractClass{ //abstract property abstract val t0: T //concrete property val t1: T = ... ... //abstract function abstract fun myAbstractFunction(t: T) //concrete function fun myFunction(t: T){ //Do Something Here... } ... }

همینطور که در بالا مشخصه در کلاس های ابسترکت، علاوه بر توابع و متغیر های concrete توابع و متغیر های abstract نیز میتونیم تعریف کنیم.

اگه ساب کلاس concrete بود توابع و پراپرتی های abstract تعریف شده در سوپر کلاس باید به صورت concrete (کامل) در subclass بازنویسی بشن

مثال

فرض کنید کلاس Foo سوپر کلاس و Bar ساب کلاس Foo است.

abstract class Foo{ abstract val prop0: String abstract fun abstractSayHello() fun concreteSayHello(){ println("Hello from concrete function!") } } class Bar: Foo{ override val prop0 = "Hello from abstract property!" override fun abstractSayHello(){ println("Hello from Abstract function!") } } fun main(){ val bar = Bar() println(bar.prop0) bar.abstractSayHello() bar.concreteSayHello() }

هنگامی که در یک کلاس abstract متغیر یا تابع abstract تعریف نکنیم معمولا به عنوان کلاس Base در نظرش میگیریم. کلاس Base پایه و سوپر کلاس تمام subclass های یک بخشی از پروژه است.

abstract class MyBase{ //without abstract properties and (or) functions ... }

مورد مطالعه (مثال ها)

در مطلب وراثت کلاس Circle و Rectangle از کلاس GeometricShape ارث بری کردن و کلاس GeometricShape از کلاس Shape.

نمودار رابطه ی بین این چهار کلاس نیز در زیر ترسیم شده:

رابطه ی ارث بری بین چهار کلاس
ارث بری از Shape و GeometricShape

حالا میخوایم دو کلاس Shape و GeometricShape رو به صورت abstract تعربف کنیم:

abstract class Shape(var color: String, var isFilled: Boolean = false){ val dateCreated = java.util.Date() override fun toString(): String{ return "Shape created at $dateCreated \ncolor is $color, \nisFilled? $isFilled" } } abstract class GeometricShape(color: String, isFilled: Boolean): Shape(color, isFilled){ abstract val area: Int abstract val perimeter: Int constructor(): this("White", false) override fun toString(): String{ return super.toString() + "\nArea is $area \nperimeter is $perimeter \nX is $x and Y is $y" } override fun equals(other: Any?): Boolean{ if(other !is GeometricShape) throw IllegalArgumentException("GeometricShape argument required") return other.area == this.area } } // تعریف کلاس دایره class Circle: GeometricShape{ var radius = 1 override val area get() = (radius * radius * PI).toInt() override val perimeter get() = (2 * radius * PI).toInt() constructor(radius: Int, color: String, isFilled: Boolean): super(color, isFilled){ this.radius = radius } constructor(): super() constructor(radius: Int): super(){ this.radius = radius } override fun toString(): String{ val fromGeometricShape = super.toString() return fromGeometricShape + "\nThe shape is Circle!" } } // تعریف کلاس مستطیل class Rectangle: GeometricShape{ var width = 1 var height = 1 override val area get() = width * height override val perimeter get() = (width + height) * 2 constructor(width: Int, height: Int, color: String, isFilled: Boolean): super(color, isFilled){ this.width = width this.height = height } constructor(): super() constructor(width: Int, height: Int): super(){ this.width = width this.height = height } fun isSquare(): Boolean = (width == height) override fun toString(): String{ val fromGeometricShape = super.toString() return fromGeometricShape + "\nThe shape is Rectangle!" } } fun main(){ val c = Circle(2) c.stroke = "Blue" val c1 = Circle(radius = 5, x = 1, y = 1, "Yellow", true) val rect = Rectangle(3 , 4) val rect1 = Rectangle(7, 7) println("$c") println("\n$c1") println("\n$rect") println("\n$rect1") println() println("Are c and rect equal? ${c.equals(rect)}") println("Are c1 and c equal? ${c1.equals(c)}" ) println() println("Is rect square? ${rect.isSquare()}") println("Is rect1 square? ${rect1.isSquare()}") }

خلاصه

به توابع و متغیر های کامل concrete میگیم.

- متغیر و پراپرتی های ابسترکت رو‌فقط داخل کلاس ابسترکت یا داهل اینترفیس مبتونیم تعریف کنیم.

در کلاس ابسترکت علاوه بر پراپرتی و توابع ابسترکت میتونیم پراپرتی و توابع کامل (concrete) نیز تعریف کنیم.

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

معمولا کلاس ابسترکتی که پراپرتی و تابع ابسترکت نداشته باشه رو به عنوان کلاس Base تعریف میکنن.

arrow_drop_up
کپی شد!