آموزش کلاس های ابستراکت (Abstract) یا انتزاعی در کاتلین

آموزش کلاس های ابستراکت (Abstract) یا انتزاعی در کاتلین

بررسی کلاس های انتزاعی (Abstract)

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

کلاس های ابستراکت (انتزاعی) دو ويژگی دارن که با کلاس های معمولی متمایزشون میکنه؛ در کلاس های انتزاعی در کاتلین علاوه بر متد و پراپرتی های معمولی میتونیم متد و پراپرتی های انتزاعی تعریف کنیم، به علاوه در این کلاس ها با وجود اینکه میتونیم کانستراکتور تعریف کنیم اما نمیتونیم ازشون آبجکت ایجاد کنیم و برای ایجاد آبجکت باید یک کلاس معمولی ازشون ارث بری کنه و آبجکت رو از کلاس معمولی ایجاد کنیم.

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

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

با اینکه میتونیم در کلاس ابستراکت (انتزاعی)، کانستراکتور تعریف کنیم اما نمیتونیم مستقیم از این کلاس ها نمونه (شی) سازی کنیم و باید از ساب کلاسی که 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 توابع و متغیر های ابستراکت (انتزاعی) نیز میتونیم تعریف کنیم.

اگه ساب کلاس concrete بود توابع و پراپرتی های ابستراکت (انتزاعی) تعریف شده در سوپر کلاس باید به صورت 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 تعریف نکنیم معمولا به عنوان کلاس Base در نظرش میگیریم. کلاس Base پایه و سوپر کلاس تمام subclass های یک بخشی از پروژه است.

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

}
                  

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

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

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

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

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

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){

  ابستراکت (انتزاعی) val area: Int
  ابستراکت (انتزاعی) 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 تعریف میکنن.

بازخورد و دیدگاه‌ ها

اولین نفری باشید که در این صفحه نظر می‌دهید

notifications برای اطلاع از جدیدترین مطالب و پست های مرتبط، عضو کانال تلگرام ما بشید.

arrow_drop_up
کپی شد!