واجهات متعددة
جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 24 من 57.
يمكن للصنف تنفيذ عدة واجهات، تفصل بينها فواصل. ويجب عليه تنفيذ أعضاء جميع هذه الواجهات:
interface Switchable {
var isOn: Boolean
fun toggle() { isOn = !isOn }
}
interface Dimmable {
var level: Int
}
class Lamp : Switchable, Dimmable {
override var isOn = false
override var level = 100
}داخل main:
val lamp = Lamp()
lamp.toggle()
lamp.level = 40
println("${lamp.isOn} ${lamp.level}")الناتج:
true 40يمكن للفئة أن ترث من فئة واحدة وتطبّق الواجهات في الرأس نفسه. وحده الصنف الفائق لديه استدعاء مُنشئ:
open class Device(val name: String)
interface Rechargeable {
fun charge(): String
}
class Phone(name: String) : Device(name), Rechargeable {
override fun charge() = "$name is charging"
}داخل main:
println(Phone("Pixel").charge())الناتج:
Pixel is chargingعندما تمنح واجهتان كلتاهما الطريقة نفسها تطبيقًا افتراضيًا، يجب على الصنف إعادة تعريفها وتحديد ما يجب فعله. تستدعي super<Name>.method() إصدار طريقة من واجهة معينة:
interface Camera {
fun describe() = "takes photos"
}
interface Telephone {
fun describe() = "makes calls"
}
class SmartPhone : Camera, Telephone {
override fun describe() = super<Telephone>.describe() + " and " + super<Camera>.describe()
}داخل main:
println(SmartPhone().describe())الناتج:
makes calls and takes photosيمكن لواجهة أن توسّع واجهات أخرى. يجب على الفئة التي تنفّذ الواجهة المدمجة توفير أعضاء جميع هذه الواجهات، وتُعدّ كل واحدة منها:
interface Named {
val name: String
}
interface Contact : Named {
val email: String
fun card() = "$name <$email>"
}
class Person(override val name: String, override val email: String) : Contactداخل main:
val ada = Person("Ada", "ada@example.com")
val named: Named = ada
println(ada.card())
println(named.name)الناتج:
Ada <ada@example.com>
Adaالتحدي
سهلSwitchable isOn (قيمة Boolean للقراءة فقط بالنسبة إلى المستدعين) وtoggle()، بينما تتطلب Dimmable قيمة brightness قابلة للكتابة. اجعل SmartLamp يطبّق كلتا الواجهتين: يبدأ وهو مطفأ وبسطوع 100، وتبدّل toggle() حالته بين التشغيل والإيقاف، وتُقيَّد قيمة السطوع خارج النطاق من 0 إلى 100 بواسطة المُعيِّن، وتُرجع status() القيمة on 70% أو off.
يقرأ الكود المُزوَّد الأوامر toggle أو رقم سطوع، ويطبّقها على مصباح واحد ويطبع status() بعد كل أمر، ثم يتحقق من أن المصباح هو Switchable وDimmable.
ضع كودك في Switchable.kt وDimmable.kt وSmartLamp.kt. يحتوي Main.kt على كود الإدخال/الإخراج المُزوَّد، ولا يمكن تعديله.
جرّب بنفسك
fun main() {
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
val input = generateSequence(::readLine).toList()
val lamp = SmartLamp()
for (cmd in input) {
if (cmd == "toggle") lamp.toggle() else lamp.brightness = cmd.toInt()
println(lamp.status())
}
println("switchable: ${(lamp as Any) is Switchable}, dimmable: ${(lamp as Any) is Dimmable}")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفينتدرّب بنفسك: Playground لـ Kotlin