تعريف الواجهات
جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 22 من 57.
تسرد الواجهة ما يمكن لنوع ما القيام به دون توضيح الكيفية. وهي تعلن عن الأساليب والخصائص التي يجب على كل فئة تنفّذها توفيرها. تنفّذ الفئة واجهة باستخدام نقطتين، كما هو الحال مع الفئة الفائقة، ولكن من دون أقواس، لأن الواجهة لا تحتوي على مُنشئ:
interface Drawable {
fun draw(): String
}
class Circle(val radius: Int) : Drawable {
override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
override fun draw() = "-".repeat(length)
}داخل main:
println(Circle(3).draw())
println(Line(5).draw())الناتج:
circle with radius 3
-----يمكن للواجهة أن تعلن عن خصائص أيضًا. يوفّرها الصنف كخصائص للمنشئ أو خصائص مخزّنة أو كـ getters؛ أما الواجهة نفسها فلا تخزّن شيئًا:
interface Vehicle {
val wheels: Int
val label: String
}
class Car(override val label: String) : Vehicle {
override val wheels = 4
}
class Bike : Vehicle {
override val wheels = 2
override val label: String
get() = "bike on $wheels wheels"
}داخل main:
println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)الناتج:
taxi: 4
bike on 2 wheelsيجب تنفيذ كل عضو تُعلنه الواجهة، مع استخدام override لكل عضو، وإلا فلن يتم تجميع الصنف. لا يمكن إنشاء مثيل من الواجهة:
interface Speaker {
fun speak(): String
val volume: Int
}
// class Mute : Speaker { override fun speak() = "" } // خطأ: volume غير مُنفَّذ
// class Loud : Speaker() { ... } // خطأ: الواجهة ليس لها مُنشئ
// val s = Speaker() // خطأ: لا يمكن إنشاء واجهةتعلن الواجهة والصنف المجرّد كلاهما عن أعضاء من دون جسم. لا تحتوي الواجهة على مُنشئ ولا على حالة مخزّنة، ويمكن للصنف تنفيذ العديد من الواجهات، لكنه لا يمكنه التوسّع إلا في صنف واحد. استخدم واجهةً لقدرة تشترك فيها أصناف غير مترابطة، مثل Drawable أو Comparable، واستخدم صنفًا مجرّدًا لقاعدة مشتركة ذات حالة.
interface Drawable { fun draw(): String } // قدرة
abstract class Shape(val name: String) { abstract fun area(): Double } // أساس مع حالة
class Square(val s: Double) : Shape("square"), Drawable { // صنف واحد، أي واجهات
override fun area() = s * s
override fun draw() = "[]"
}التحدي
سهلصرّح بأعضاء الواجهة Shape: خاصية للقراءة فقط name والطريقتين area() وperimeter()، وكلتاهما تُرجعان Double. اجعل Rectangle(width, height) (الاسم rectangle) وCircle(radius) (الاسم circle، باستخدام Math.PI) تنفّذانهما. ثم أكمل describe(shape)، التي تُرجع rectangle: area 12.00, perimeter 14.00 بمنزلتين عشريتين، باستخدام أعضاء Shape فقط.
يقرأ الكود المزوَّد أسطرًا مثل r,3,4 أو c,2، وينشئ الشكل المطابق ويطبع describe(shape).
ضع الكود الخاص بك في Shape.kt وRectangle.kt وCircle.kt وFunctions.kt. يحتوي Main.kt على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.
جرّب بنفسك
fun main() {
// كود الإدخال/الإخراج المُزوَّد: أبقه كما هو
val input = generateSequence(::readLine).toList()
for (line in input) {
val p = line.split(",").map { it.trim() }
val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
println(describe(shape))
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفينتدرّب بنفسك: Playground لـ Kotlin