logo

تعدد الأشكال في جاوة

تعدد الأشكال في جاوة هو المفهوم الذي يمكننا من خلاله أداء عمل واحد بطرق مختلفة . تعدد الأشكال مشتق من كلمتين يونانيتين: poly و morphs. كلمة 'poly' تعني العديد وكلمة 'morphs' تعني الأشكال. لذا فإن تعدد الأشكال يعني أشكالاً عديدة.

هناك نوعان من تعدد الأشكال في Java: تعدد الأشكال في وقت الترجمة وتعدد الأشكال في وقت التشغيل. يمكننا تنفيذ تعدد الأشكال في جافا عن طريق التحميل الزائد وتجاوز الطريقة.

إذا قمت بتحميل طريقة ثابتة في Java بشكل زائد، فهذا مثال على تعدد أشكال وقت الترجمة. سنركز هنا على تعدد الأشكال في وقت التشغيل في Java.

جافا عفوا المفاهيم

تعدد الأشكال في وقت التشغيل في جافا

تعدد الأشكال في وقت التشغيل أو إرسال الطريقة الديناميكية هي عملية يتم فيها حل استدعاء الأسلوب المتجاوز في وقت التشغيل بدلاً من وقت الترجمة.

في هذه العملية، يتم استدعاء الأسلوب المتجاوز من خلال المتغير المرجعي للفئة الفائقة. يعتمد تحديد الطريقة التي سيتم استدعاؤها على الكائن المشار إليه بواسطة المتغير المرجعي.

دعونا أولاً نفهم الترقية قبل تعدد الأشكال في وقت التشغيل.

نبذ

إذا كان المتغير المرجعي للفئة الأصل يشير إلى كائن للفئة التابعة، فإنه يُعرف باسم البث. على سبيل المثال:

Upcasting في جافا
 class A{} class B extends A{} 
 A a=new B();//upcasting 

من أجل البث، يمكننا استخدام المتغير المرجعي لنوع الفئة أو نوع الواجهة. على سبيل المثال:

 interface I{} class A{} class B extends A implements I{} 

هنا، ستكون العلاقة بين الفئة B:

 B IS-A A B IS-A I B IS-A Object 

نظرًا لأن الكائن هو الفئة الجذرية لجميع الفئات في Java، فيمكننا كتابة كائن B IS-A.


مثال على تعدد أشكال Java Runtime

في هذا المثال، نقوم بإنشاء فئتين Bike و Splendor. تعمل فئة Splendor على توسيع فئة Bike وتتجاوز طريقة التشغيل () الخاصة بها. نحن نطلق على طريقة التشغيل المتغير المرجعي للفئة الأصل. نظرًا لأنه يشير إلى كائن الفئة الفرعية وطريقة الفئة الفرعية تتجاوز طريقة الفئة الأصل، يتم استدعاء طريقة الفئة الفرعية في وقت التشغيل.

نظرًا لأن استدعاء الطريقة يتم تحديده بواسطة JVM وليس المترجم، فإنه يُعرف باسم تعدد الأشكال في وقت التشغيل.

 class Bike{ void run(){System.out.println('running');} } class Splendor extends Bike{ void run(){System.out.println('running safely with 60km');} public static void main(String args[]){ Bike b = new Splendor();//upcasting b.run(); } } 
اختبره الآن

انتاج:

 running safely with 60km. 

مثال على تعدد أشكال وقت تشغيل Java: Bank

فكر في سيناريو حيث يكون البنك فئة توفر طريقة للحصول على سعر الفائدة. ومع ذلك، قد يختلف سعر الفائدة باختلاف البنوك. على سبيل المثال، تقدم بنوك SBI وICICI وAXIS معدلات فائدة تبلغ 8.4% و7.3% و9.7%.

Java Runtime Polymorphism مثال على البنك

ملاحظة: تم تقديم هذا المثال أيضًا في طريقة التجاوز ولكن لم يكن هناك أي نقل للأعلى.

 class Bank{ float getRateOfInterest(){return 0;} } class SBI extends Bank{ float getRateOfInterest(){return 8.4f;} } class ICICI extends Bank{ float getRateOfInterest(){return 7.3f;} } class AXIS extends Bank{ float getRateOfInterest(){return 9.7f;} } class TestPolymorphism{ public static void main(String args[]){ Bank b; b=new SBI(); System.out.println('SBI Rate of Interest: '+b.getRateOfInterest()); b=new ICICI(); System.out.println('ICICI Rate of Interest: '+b.getRateOfInterest()); b=new AXIS(); System.out.println('AXIS Rate of Interest: '+b.getRateOfInterest()); } } 
اختبره الآن

انتاج:

 SBI Rate of Interest: 8.4 ICICI Rate of Interest: 7.3 AXIS Rate of Interest: 9.7 

مثال على تعدد الأشكال في وقت تشغيل Java: الشكل

 class Shape{ void draw(){System.out.println('drawing...');} } class Rectangle extends Shape{ void draw(){System.out.println('drawing rectangle...');} } class Circle extends Shape{ void draw(){System.out.println('drawing circle...');} } class Triangle extends Shape{ void draw(){System.out.println('drawing triangle...');} } class TestPolymorphism2{ public static void main(String args[]){ Shape s; s=new Rectangle(); s.draw(); s=new Circle(); s.draw(); s=new Triangle(); s.draw(); } } 
اختبره الآن

انتاج:

 drawing rectangle... drawing circle... drawing triangle... 

مثال على تعدد الأشكال في وقت تشغيل Java: Animal

 class Animal{ void eat(){System.out.println('eating...');} } class Dog extends Animal{ void eat(){System.out.println('eating bread...');} } class Cat extends Animal{ void eat(){System.out.println('eating rat...');} } class Lion extends Animal{ void eat(){System.out.println('eating meat...');} } class TestPolymorphism3{ public static void main(String[] args){ Animal a; a=new Dog(); a.eat(); a=new Cat(); a.eat(); a=new Lion(); a.eat(); }} 
اختبره الآن

انتاج:

ريجكس جافا
 eating bread... eating rat... eating meat... 

تعدد أشكال Java Runtime مع عضو البيانات

يتم تجاوز الطريقة، وليس أعضاء البيانات، لذلك لا يمكن تحقيق تعدد الأشكال في وقت التشغيل بواسطة أعضاء البيانات.

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

القاعدة: لا يمكن لأعضاء البيانات تحقيق تعدد الأشكال في وقت التشغيل.

 class Bike{ int speedlimit=90; } class Honda3 extends Bike{ int speedlimit=150; public static void main(String args[]){ Bike obj=new Honda3(); System.out.println(obj.speedlimit);//90 } } 
اختبره الآن

انتاج:

 90 

جافا تعدد الأشكال في وقت التشغيل مع الوراثة متعددة المستويات

دعونا نرى المثال البسيط لتعدد الأشكال في وقت التشغيل مع الميراث متعدد المستويات.

 class Animal{ void eat(){System.out.println('eating');} } class Dog extends Animal{ void eat(){System.out.println('eating fruits');} } class BabyDog extends Dog{ void eat(){System.out.println('drinking milk');} public static void main(String args[]){ Animal a1,a2,a3; a1=new Animal(); a2=new Dog(); a3=new BabyDog(); a1.eat(); a2.eat(); a3.eat(); } } 
اختبره الآن

انتاج:

 eating eating fruits drinking Milk 

حاول للإخراج

 class Animal{ void eat(){System.out.println('animal is eating...');} } class Dog extends Animal{ void eat(){System.out.println('dog is eating...');} } class BabyDog1 extends Dog{ public static void main(String args[]){ Animal a=new BabyDog1(); a.eat(); }} 
اختبره الآن

انتاج:

 Dog is eating 

نظرًا لأن BabyDog لا يتجاوز طريقة Eat()، لذلك يتم استدعاء طريقة Eat() لفئة Dog.