Polymorphism: dynamic dispatch and toString() · تعدد الأشكال: التوزيع الديناميكي وtoString()
Polymorphism: one type, many behaviours
- Polymorphism means "many forms": one superclass type, many subclass behaviours.
- You can hold a
Dogor aCatin anAnimalvariable, because each is-anAnimal. - When you call a method, the object's real type decides which version runs.
تعدد الأشكال: نوع واحد، سلوكيات عديدة
- تعدد الأشكال يعني "أشكال كثيرة": نوع فئة أب واحد، سلوكيات عدة فئات ابنة.
- يمكنك حمل
DogأوCatفي متغيرAnimal، لأن كل هو نوع منAnimal. - عندما تستدعي طريقة، النوع الحقيقي للكائن يحدد أي نسخة تُنفذ.
Dynamic dispatch
- The variable's type (
Animal) decides which methods you are allowed to call. - But at run time, the actual object (
Dog) decides which overridden version runs. - This run-time choice is called dynamic dispatch — it is the heart of polymorphism.
التوزيع الديناميكي
- نوع المتغير (
Animal) يحدد أي الطرق مسموح لك باستدعاؤها. - لكن عند وقت التشغيل، الكائن الفعلي (
Dog) يحدد أي نسخة مُعاد تعريفها ستُنفذ. - يُسمى هذا الاختيار وقت التشغيل بـ التوزيع الديناميكي — وهو قلب تعدد الأشكال.
public class Main {
public static void main(String[] args) {
Animal[] zoo = { new Dog(), new Cat(), new Dog() };
for (Animal a : zoo) {
System.out.println(a.speak()); // Woof, then Meow, then Woof
}
}
}
class Animal {
public String speak() { return "some sound"; }
}
class Dog extends Animal {
public String speak() { return "Woof"; }
}
class Cat extends Animal {
public String speak() { return "Meow"; }
}
One loop handles every subclass
- The loop above never asks "is this a Dog or a Cat?" — it just calls
speak(). - Each object answers in its own way. That keeps the loop short and general.
- Add a brand-new subclass later and the same loop works on it, unchanged.
حلقة واحدة تتعامل مع كل فئة فرعية
- الحلقة أعلاه لا تسأل أبدًا "هل هذا كلب أم قطة؟" — بل تستدعي
speak()مباشرةً. - كل كائن يُجيب بطريقة خاصة به. هذا يحافظ على الحلقة قصيرة وعامة.
- أضف فئة فرعية جديدة لاحقًا وستعمل عليها نفس الحلقة، دون تغيير.
toString(): every object inherits it from Object
- Every class in Java secretly extends a class called
Object, which has atoString(). - Override
toString()to say how your object should look as text. - Java calls it automatically when you print an object or join it with
+.
toString(): يرثه كل كائن من Object
- كل فئة في Java تمتد سراً بفئة تُسمى
Object، والتي تحتوي علىtoString(). - أعد تعريف
toString()لوصف كيفية ظهور كائنك كنص. - تطلب منه Java تلقائيًا عندما تطبع كائنًا أو تربطه بـ
+.
public class Main {
public static void main(String[] args) {
Object x = new Fraction(3, 4);
System.out.println(x); // 3/4 -- toString() runs
System.out.println("ratio " + x); // ratio 3/4
}
}
class Fraction {
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public String toString() {
return numerator + "/" + denominator;
}
}
Common mistakes
- The actual object's method runs at run time (dynamic dispatch), not the variable's type.
- Override
toString()for readable output.
أخطاء شائعة
- تُنفذ طريقة الكائن الفعلي وقت التشغيل (التوزيع الديناميكي)، وليس نوع المتغير.
- أعد تعريف
toString()للحصول على مخرجات مقروءة.
Now you try
- Use a superclass array, add a new subclass, and override
toString(). - A hidden Harness checks that the right version runs for each object.
- Press Run to compile, then Check answer. Your code runs on the server, so even the first run is fast.
الآن جرب بنفسك
- استخدم مصفوفة فائقة، وأضف فئة فرعية جديدة، وأعد تعريف
toString(). - يقوم مختبر خفي بالتحقق من أن النسخة الصحيحة تنفذ لكل كائن.
- اضغط Run للمترجمة، ثم Check answer. يعمل كودك على الخادم، لذا حتى أول تشغيل سريع.
Animal, Dog, and Cat are written for you. Complete the static method Zoo.chorus(Animal[] animals) so it returns every animal's sound joined by single spaces. Example: a Dog, Cat, Dog array gives "Woof Meow Woof". An empty array gives "". Loop and call speak() — let polymorphism pick the right sound. · Animal، Dog، وCat مكتوبة لك. أتمم الدالة الثابتة Zoo.chorus(Animal[] animals) لتُرجع أصوات كل حيوان مفصولة بمسافات فردية. مثال: مصفوفة Dog، Cat، Dog تُنتج "Woof Meow Woof". مصفوفة فارغة تُنتج "". مرر حلقة واستدعِ speak() — دع تعدد الأشكال يختار الصوت الصحيح.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.
Animal, Dog, Cat, and a working Zoo.chorus are written for you. Add a class Cow that extends Animal and overrides speak() to return "Moo". Notice the existing chorus loop handles your new Cow with no changes. · Animal، Dog، Cat، ودالة Zoo.chorus العاملة مكتوبة لك. أضف فئة Cow تمتد من Animal وتعدل speak() لتُرجع "Moo". لاحظ أن الحلقة chorus الموجودة تتعامل مع البقرة الجديدة الخاصة بك بدون تغييرات.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.
Complete Fraction by overriding toString() so it returns the fraction as "numerator/denominator" — for 3 and 4 it returns "3/4". Java calls toString() automatically when you print a Fraction or join it with +. · أتمم Fraction بتعديل toString() لتُرجع الكسر كـ "numerator/denominator" — بالنسبة لـ 3 و4 تُرجع "3/4". يستدعي Java toString() تلقائياً عند طباعة Fraction أو دمجها مع +.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.