Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

حجب الـ Methods المضمنة

جزء من قسم البرمجة كائنية التوجه في رحلة GO على Coddy. الدرس 39 من 107.

أحيانًا تحتاج البنية الخارجية إلى توفير تنفيذها الخاص لطريقة يمتلكها النوع المضمّن بالفعل. يُسمّى هذا الحجب، ويتيح لك تجاوز الطرق المُروَّجة بسلوك مخصّص.

عندما تعرّف طريقةً على البنية الخارجية بالاسم نفسه لطريقة مضمنة، تكون الأولوية للطريقة الخارجية:

type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return "Some sound"
}

type Dog struct {
    Animal
    Breed string
}

func (d Dog) Speak() string {
    return "Woof!"
}

الآن عند استدعاء Speak() على Dog، تُستخدم الطريقة الخارجية:

func main() {
    d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
    
    fmt.Println(d.Speak())        // Woof! - طريقة Dog
    fmt.Println(d.Animal.Speak()) // Some sound - طريقة Animal
}

إن method الـ embedded لم تختفِ. لا يزال بإمكانك الوصول إليها explicitly من خلال اسم النوع الـ embedded. يكون هذا النمط مفيدًا عندما تريد تخصيص السلوك مع الإبقاء على التنفيذ الأصلي متاحًا، وربما لاستخدامه من داخل method التي تتولى التجاوز:

func (d Dog) Speak() string {
    return d.Animal.Speak() + " (but actually Woof!)"
}

يمنحك حجب الاسم تحكّمًا في السلوك الذي يتم كشفه، مع الحفاظ على إمكانية الوصول إلى الأصل من خلال التأهيل الصريح.

challenge icon

التحدي

سهل

لنُنشئ نظام إشعارات يمكن فيه لقنوات الإشعارات المختلفة تخصيص طريقة تنسيق الرسائل وتسليمها. ستستخدم تظليل method للسماح لقنوات محددة بتجاوز السلوك الافتراضي، مع إمكانية الوصول إلى التنفيذ الأصلي عند الحاجة.

ستنظّم التعليمات البرمجية عبر ثلاثة ملفات:

  • base.go: أنشئ بنية BaseNotification مع حقلي Title وPriority (وكلاهما من نوع string). أضف إليها أسلوب Format() string يعيد notification بالتنسيق القياسي: [Priority] Title.
  • channels.go: أنشئ نوعين من قنوات الإشعارات يضمّنان BaseNotification ويظلّلان أسلوب Format بتنفيذاتهما الخاصة:
    • EmailNotification مع حقل Recipient. يجب أن يعيد Format() القيمة Email to [Recipient]: [Priority] Title
    • SlackNotification مع حقل Channel. يجب أن يستدعي Format() الخاص بالأسلوب المضمّن BaseNotification.Format() ويضيف #[Channel]: في بداية النتيجة
  • main.go: اقرأ تفاصيل الإشعار من الإدخال، وأنشئ كلا النوعين من الإشعارات، وأثبت التظليل بطباعة ما يلي:
    1. الناتج المنسّق لـ EmailNotification (باستخدام أسلوبه المظلّل)
    2. التنسيق الأساسي لـ EmailNotification (باستدعاء الأسلوب المضمّن بشكل صريح)
    3. الناتج المنسّق لـ SlackNotification (الذي يستخدم داخليًا الأسلوب الأساسي)

سيتم توفير المدخلات التالية:

  • السطر 1: عنوان الإشعار
  • السطر 2: مستوى الأولوية
  • السطر 3: مستلم البريد الإلكتروني
  • السطر 4: اسم قناة Slack

على سبيل المثال، عند إعطاء Server Alert وHIGH وadmin@company.com وops-alerts، يجب أن يكون الناتج كما يلي:

Email to admin@company.com: HIGH Server Alert
[HIGH] Server Alert
#ops-alerts: [HIGH] Server Alert

لاحظ كيف يستبدل EmailNotification تنسيق base بالكامل، بينما يحسّنه SlackNotification باستدعاء الأسلوب الأصلي وإضافة سياق القناة. يوضّح كلا النهجين طرقًا مختلفة لاستخدام تظليل method بفعالية.

جرّب بنفسك

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// اقرأ عنوان الإشعار
	scanner.Scan()
	title := scanner.Text()
	
	// اقرأ مستوى الأولوية
	scanner.Scan()
	priority := scanner.Text()
	
	// اقرأ مستلم البريد الإلكتروني
	scanner.Scan()
	recipient := scanner.Text()
	
	// اقرأ اسم قناة Slack
	scanner.Scan()
	channel := scanner.Text()
	
	// TODO: أنشئ EmailNotification مع الإشعار الأساسي و title و priority و recipient
	
	// TODO: أنشئ SlackNotification مع الإشعار الأساسي و title و priority و channel
	
	// TODO: اطبع المخرجات المنسقة لـ EmailNotification (باستخدام method المظلل الخاص به)
	
	// TODO: اطبع التنسيق الأساسي لـ EmailNotification (باستدعاء الـ method المضمّن صراحةً)
	
	// TODO: اطبع المخرجات المنسقة لـ SlackNotification
	
	fmt.Println() // عنصر نائب - أزله عند التنفيذ
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Go عبر الإنترنت