Menu
CoddyTech

إعادة النظر في تجاوز الأساليب

جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 21 من 65.

تعدد الأشكال يعني «أشكالًا متعددة»: استدعاء واحد للدالة يؤدي أشياء مختلفة حسب صنف الكائن الذي يستقبله. إعادة التعريف هي ما يجعل ذلك ممكنًا.

# animal.gd
class_name Animal
extends RefCounted

func speak() -> String:
	return "..."
# dog.gd
class_name Dog
extends Animal

func speak() -> String:
	return "Woof!"
# cat.gd
class_name Cat
extends Animal

func speak() -> String:
	return "Meow!"

يمكن لمصفوفة Array[Animal] أن تحتوي عليها جميعًا. تستدعي الحلقة speak() دون معرفة الفئة التي ينتمي إليها كل عنصر، ويجيب كل كائن بنسخته الخاصة:

var animals: Array[Animal] = [Dog.new(), Cat.new(), Animal.new()]
for animal in animals:
	print(animal.speak())
Woof!
Meow!
...

تعمل الدالة ذات المعامل Animal بالطريقة نفسها. فهي تقبل كل فئة فرعية، بما في ذلك الفئات التي تضيفها لاحقًا، دون أي تغيير:

func make_it_speak(animal: Animal) -> void:
	print("It says ", animal.speak())
make_it_speak(Cat.new())
It says Meow!

قارن هذا بالتحقق من الفئات واحدة تلو الأخرى. يجب أن تتوسع سلسلة الفروع if animal is Dog: مع كل فئة جديدة. باستخدام إعادة التعريف، تحمل كل فئة سلوكها الخاص، ويظل الكود الذي يستدعيها كما هو.

challenge icon

التحدي

سهل

يتعامل المرآب مع كل مركبة من خلال Array[Vehicle] واحدة. في vehicle.gd، تُرجع wheels() القيمة 0 وتُرجع sound() القيمة ....

  • اكتب describe() في Vehicle. تُرجع BRAND: N wheels, SOUND، مع استدعاء wheels() وsound().
  • تُعيد Car تعريف wheels() لتُرجع 4، وsound() لتُرجع Vroom.
  • تُعيد Motorcycle تعريفهما لتُرجعا 2 وBrrm.
  • يخزّن Truck بالفعل عدد trailers. يُعيد تعريف wheels() لتُرجع 6 بالإضافة إلى 4 لكل مقطورة، وsound() لتُرجع Honk.

لا تعيد الفئات الفرعية تعريف describe(). يقرأ الكود المرفق عدد المركبات التالية، ثم سطرًا واحدًا لكل مركبة: car BRAND أو motorcycle BRAND أو truck BRAND TRAILERS أو vehicle BRAND. يطبع نتيجة كل استدعاء لـdescribe() ومجموع قيم wheels(). عند إدخال car Toyota وtruck Volvo 2، يطبع:

Toyota: 4 wheels, Vroom
Volvo: 14 wheels, Honk
Total wheels: 18

ضع الكود في vehicle.gd وcar.gd وmotorcycle.gd وtruck.gd. يحتوي main.gd على كود الإدخال والإخراج المرفق، ولا يمكن تعديله.

جرّب بنفسك

extends Node

func _ready():
	# كود الإدخال/الإخراج المقدَّم: اتركه كما هو
	var count := int(OS.read_string_from_stdin())
	var vehicles: Array[Vehicle] = []
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		if p[0] == "car":
			vehicles.append(Car.new(p[1]))
		elif p[0] == "motorcycle":
			vehicles.append(Motorcycle.new(p[1]))
		elif p[0] == "truck":
			vehicles.append(Truck.new(p[1], int(p[2])))
		else:
			vehicles.append(Vehicle.new(p[1]))
	var total := 0
	for v in vehicles:
		print(v.describe())
		total += v.wheels()
	print("Total wheels: %d" % total)
quiz iconاختبر نفسك

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

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

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