التفويض إلى الأعضاء
ركّبوا السلوك
التفويض إلى الأعضاء درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
تركيب السلوك
غالبًا ما تحتاج الكائنات الحقيقية إلى الجمع بين عدة إمكانات. وبدلًا من التوريث من مصادر متعددة، يمكنك تفويض كل إمكان إلى كائن عضو مخصص.
دوران وفئة واحدة
لنفترض أن على فئة ما القراءة والكتابة معًا. عرّف واجهتين وفوّض كل واحدة إلى تنفيذها الخاص.
interface Reader { fun read(): String }
interface Writer { fun write(s: String): String }
class FileReader : Reader { override fun read() = "contents" }
class FileWriter : Writer { override fun write(s: String) = "wrote " + s }
class FileIO(r: Reader, w: Writer) : Reader by r, Writer by w
fun main() {
val io = FileIO(FileReader(), FileWriter())
println(io.read())
println(io.write("data"))
}مفوَّضون متعددون
يمكن للفئة تفويض عدة واجهات في آنٍ واحد، كل واجهة إلى عضو مختلف. وهكذا تركّب الفئة سلوكياتها من دون توريث.
interface Logger { fun log(m: String): String }
interface Validator { fun valid(m: String): Boolean }
class ConsoleLogger : Logger { override fun log(m: String) = "LOG: " + m }
class LengthValidator : Validator { override fun valid(m: String) = m.isNotEmpty() }
class Service(l: Logger, v: Validator) : Logger by l, Validator by v
fun main() {
val s = Service(ConsoleLogger(), LengthValidator())
println(s.valid("hi"))
println(s.log("started"))
}تخزين المفوَّض كعضو
عندما تحتاج إلى الرجوع إلى المفوَّض داخل عمليات إعادة التعريف، احتفظ به كخاصية في المُنشئ. ويدعم المثيل نفسه كلًا من إعادة التوجيه وكودك المخصص.
interface Cache { fun get(k: String): String }
class MapCache : Cache {
override fun get(k: String) = "value-of-" + k
}
class TracingCache(private val inner: Cache) : Cache by inner {
override fun get(k: String): String {
println("lookup " + k)
return inner.get(k)
}
}
fun main() {
println(TracingCache(MapCache()).get("id"))
}مزج التفويض مع الحالة الخاصة
يمكن للفئة التي تستخدم التفويض إضافة خصائصها وأساليبها الخاصة إلى جانب الأعضاء المُعاد توجيههم، مما يثري الكائن المركّب.
interface Engine { fun start(): String }
class V8 : Engine { override fun start() = "vroom" }
class Car(e: Engine) : Engine by e {
var doors = 4
fun honk() = "beep"
}
fun main() {
val c = Car(V8())
println(c.start())
println(c.honk())
println(c.doors)
}تبديل التطبيقات
بما أن المفوَّض مجرد عضو، يمكنك إنشاء الحاوية نفسها باستخدام تطبيقات داعمة مختلفة، واختيار السلوك أثناء التشغيل.
interface Notifier { fun send(msg: String): String }
class EmailNotifier : Notifier { override fun send(msg: String) = "email: " + msg }
class SmsNotifier : Notifier { override fun send(msg: String) = "sms: " + msg }
class Alerts(n: Notifier) : Notifier by n
fun main() {
println(Alerts(EmailNotifier()).send("hi"))
println(Alerts(SmsNotifier()).send("hi"))
}التفويض إلى خاصية
يمكن أن يكون التعبير الذي يلي by أي تعبير يُقيَّم مرة واحدة، بما في ذلك استدعاء مُنشئ. ولا يشترط أن يكون معاملًا.
interface Greeter { fun greet() = "hi" }
class DefaultGreeter : Greeter
class Page : Greeter by DefaultGreeter()
fun main() {
println(Page().greet())
}تجنب مشكلة الماسة
لا يمكن توريث السلوك من عدة فئات، لكن تفويض عدة واجهات إلى أعضاء منفصلين يتجاوز مشكلة الماسة التقليدية بطريقة نظيفة.
interface A { fun a() = "A" }
interface B { fun b() = "B" }
class AImpl : A
class BImpl : B
class Combined : A by AImpl(), B by BImpl()
fun main() {
val c = Combined()
println(c.a() + c.b())
}التصميم من أجل التركيب
لتحقيق تركيب جيد:
- عرّف واجهات صغيرة ومركّزة
- وفّر تطبيقات قابلة لإعادة الاستخدام
- فوّض كل دور في الفئة المركِّبة
يحافظ ذلك على مرونة الفئات وقابليتها للاختبار.
مراجعة التفويض إلى الأعضاء
يتيح التفويض إلى كائنات الأعضاء للفئة تجميع السلوك من أجزاء مختلفة. ويمكنك دمج واجهات عديدة، وإعادة تعريف الأعضاء انتقائيًا، وتبديل التطبيقات، وإضافة حالتك الخاصة — وكل ذلك من دون توريث.
التالي: مقارنة مباشرة
لقد رأيت مدى مرونة التفويض. يقارن الدرس التالي بين التفويض والتوريث مباشرةً، حتى تعرف متى تختار كلًا منهما.
اختبار سريع
اختبر فهمك للتفويض إلى الأعضاء.
مراجعة
لقد تعلّمت التفويض إلى الأعضاء:
- تفويض عدة واجهات إلى كائنات منفصلة
- إعادة التعريف انتقائيًا وإضافة الحالة الخاصة
- تبديل التطبيقات عند الإنشاء
- تجنب مشكلات التوريث المتعدد
التالي: التفويض مقابل التوريث.
الأسئلة الشائعة
هل درس «التفويض إلى الأعضاء» مجاني؟
نعم — نص درس «التفويض إلى الأعضاء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
ماذا ستتعلم في «التفويض إلى الأعضاء»؟
ركّبوا السلوك تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟
لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «التفويض إلى الأعضاء»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟
نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الكلمة المفتاحية by
- التفويض إلى الأعضاء
- التفويض مقابل الوراثة
- أنماط عملية