ما هو تعدد الأشكال ، ما هو من أجل ، وكيف يتم استخدامه؟

StackOverflow https://stackoverflow.com/questions/1031273

سؤال

ما هو تعدد الأشكال ، ما هو من أجل ، وكيف يتم استخدامه؟

هل كانت مفيدة؟

المحلول

إذا كنت تفكر في الجذور اليونانية للمصطلح ، فيجب أن يصبح ذلك واضحًا.

  • poly = كثير: مضلع = متعدد الجوانب ، البوليسترين = العديد من الأناقة (أ), ، polyglot = العديد من اللغات ، وهلم جرا.
  • morph = التغيير أو الشكل: التشكل = دراسة الشكل البيولوجي ، morpheus = إله الأحلام اليونانية قادرة على اتخاذ أي شكل.

لذا فإن تعدد الأشكال هو القدرة (في البرمجة) على تقديم نفس الواجهة للاختلاف النماذج الأساسية (أنواع البيانات).

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

ولكن ، بنفس الطريقة ، مثل فئة BigDecimal أو Rational أو Imaginary يمكن أيضًا توفير تلك العمليات ، على الرغم من أنها تعمل على أنواع البيانات المختلفة.

المثال الكلاسيكي هو Shape الطبقة وجميع الفصول التي يمكن أن ترث منها (مربع ، دائرة ، دوديكاهدرون ، مضلع غير منتظم ، splat وما إلى ذلك).

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

من خلال جعل الفصل مسؤولاً عن الكود وكذلك بياناته ، يمكنك تحقيق تعدد الأشكال. في هذا المثال ، سيكون لكل فصل خاص به Draw() الوظيفة ويمكن أن تفعل رمز العميل ببساطة:

shape.Draw()

للحصول على السلوك الصحيح لأي شكل.

هذا على عكس الطريقة القديمة لعمل الأشياء التي كان فيها الرمز منفصلًا عن البيانات ، وكان لديك وظائف مثل drawSquare() و drawCircle().

توجيه الكائنات ، تعدد الأشكال والميراث ، كلها مفاهيم متعلقة بعناية وهي أمر حيوي لمعرفة. كان هناك العديد من "الرصاص الفضي" خلال مسيرتي الطويلة التي تلاشت في الأساس ، لكن نموذج OO قد تحول إلى نقطة جيدة. تعلمها ، افهمها ، أحبها - ستكون سعيدًا لأنك فعلت :-)


(أ) لقد كتبت في الأصل أن هذه مزحة ولكن اتضح أنها صحيحة ، وبالتالي ليست مضحكة. تصنع الستايرين موممير من الكربون والهيدروجين ، C8H8, ، والبوليسترين مصنوع من مجموعات من ذلك ، (C8H8)ن.

ربما كان ينبغي عليّ أن أذكر أن الاورام الحميدة كانت العديد من حوادث الرسالة p على الرغم من أنني الآن بعد أن اضطررت إلى شرح النكتة ، حتى أن هذا لا يبدو مضحكا أيضًا.

في بعض الأحيان ، يجب أن تستقيل أثناء خلفك :-)

نصائح أخرى

تعدد الأشكال هو عندما يمكنك التعامل مع كائن كإصدار عام من شيء ما ، ولكن عند الوصول إليه ، يحدد الكود النوع الدقيق الذي هو عليه ويتصل بالرمز المرتبط به.

هنا مثال في C#. قم بإنشاء أربع فئات ضمن تطبيق وحدة التحكم:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

الآن قم بإنشاء ما يلي في Main () من الوحدة النمطية لتطبيق وحدة التحكم:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

في هذا المثال ، نقوم بإنشاء قائمة بمركبة الفئة الأساسية ، والتي لا تعرف عدد العجلات التي تتمتع بها كل من فئاتها الفرعية ، ولكنها تعرف أن كل فئة فرعية مسؤولة عن معرفة عدد العجلات التي لديها.

ثم نضيف دراجة وسيارة وشاحنة إلى القائمة.

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

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

آمل أن يكون هذا يساعدك.

من فهم وتطبيق تعدد الأشكال في PHP, ، شكرا ستيف جديتي.

تعدد الأشكال هو كلمة طويلة لمفهوم بسيط للغاية.

يصف تعدد الأشكال نمطًا في البرمجة الموجهة للكائنات التي يكون فيها الفئات وظائف مختلفة أثناء مشاركة واجهة مشتركة.

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

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

إذا كان أي شخص يقول قطع هؤلاء الناس

  1. الجراح
  2. مصفف الشعر
  3. الممثل

ماذا سيحدث؟

  • سيبدأ الجراح في إجراء شق.
  • سيبدأ مصفف الشعر في قطع شعر شخص ما.
  • سيتوقف الممثل فجأة عن التصرف من المشهد الحالي ، في انتظار إرشادات الإخراج.

لذلك يوضح التمثيل ما هو تعدد الأشكال (الاسم نفسه ، سلوك مختلف) في OOP.

إذا كنت ستذهب لإجراء مقابلة وتطلب من المقابلة أن تخبر/تظهر مثالًا مباشرًا على تعدد الأشكال في نفس الغرفة التي نجلس فيها ، على سبيل المثال-

الإجابة - الباب / النوافذ

أتساءل كيف؟

من خلال الباب / النافذة - يمكن أن يأتي الشخص ، يمكن أن يأتي الهواء ، يمكن أن يأتي الضوء ، يمكن أن يأتي المطر ، إلخ.

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

شرح بسيط عن طريق القياس

رئيس الولايات المتحدة يوظف تعدد الأشكال. كيف؟ حسنًا ، لديه العديد من المستشارين:

  1. المستشارون العسكريون
  2. المستشارون القانونيون
  3. الفيزيائيون النوويون (كمستشارين)
  4. المستشارون الطبيون
  5. الخ.

يجب أن يكون الجميع مسؤولين فقط عن شيء واحد: مثال:

الرئيس ليس خبيرًا في طلاء الزنك ، أو فيزياء الكم. إنه لا يعرف أشياء كثيرة - لكنه يعرف شيئًا واحدًا فقط: كيفية إدارة البلاد.

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

لماذا هذه فكرة سيئة أن يعرف الرئيس كل هذه الأشياء المحددة؟

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

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

هل هناك طريقة أفضل؟

هناك نهج أفضل: لا يحتاج الرئيس إلى معرفة تفاصيل أي شيء - يمكنه المطالبة بأفضل نصيحة ، من الأشخاص المكلفين بالتحديد بالقيام بهذه الأشياء.

يمكنه استخدام نهج متعدد الأشكال لإدارة البلاد.

مثال - على استخدام نهج متعدد الأشكال:

كل ما يفعله الرئيس هو مطالبة الناس بتقديم المشورة له - وهذا ما يفعله بالفعل في الحياة الحقيقية - وهذا ما يجب أن يفعله الرئيس الجيد. يستجيب مستشاروه جميعهم بشكل مختلف ، لكنهم يعرفون جميعًا ما يعنيه الرئيس: المشورة (). لقد حصل على مئات الأشخاص الذين يتدفقون في مكتبه. لا يهم في الواقع من هم. كل ما يعرفه الرئيس هو أنه عندما يطلب منهم "تقديم المشورة" ، فإنهم يعرفون كيفية الرد وفقًا لذلك:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // assume the Petraeus and Condi classes etc are instantiated.
        petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
        condolezza.Advise(); // # she says negotiate trade deal with Iran
        healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
    }
}

يتيح هذا النهج للرئيس إدارة البلاد حرفيًا دون معرفة أي شيء عن الأشياء العسكرية أو الرعاية الصحية أو الدبلوماسية الدولية: يتم ترك التفاصيل للخبراء. الشيء الوحيد الذي يحتاج الرئيس إلى معرفته هو: "المشورة ()".

ما لا تريده:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // people walk into the Presidents office and he tells them what to do
        // depending on who they are.

        // Fallujah Advice - Mr Prez tells his military exactly what to do.
        petraeus.IncreaseTroopNumbers();
        petraeus.ImproveSecurity();
        petraeus.PayContractors();

        // Condi diplomacy advice - Prez tells Condi how to negotiate

        condi.StallNegotiations();
        condi.LowBallFigure();
        condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();

        // Health care

        healthOfficial.IncreasePremiums();
        healthOfficial.AddPreexistingConditions();
    }
}

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

يتيح ذلك للرئيس أن يفعل ما يفعله بشكل أفضل: تعيين السياسة العامة ، وتبدو جيدة ولعب الجولف: ص.

كيف يتم تنفيذها بالفعل - من خلال فئة قاعدة أو واجهة مشتركة

هذا في الواقع هو تعدد الأشكال ، باختصار. كيف يتم ذلك بالضبط؟ من خلال "تنفيذ واجهة مشتركة" أو باستخدام فئة قاعدة (الميراث) - راجع الإجابات أعلاه التي تفصل هذا بشكل أوضح. (من أجل فهم هذا المفهوم بشكل أوضح ، تحتاج إلى معرفة ماهية الواجهة ، وستحتاج إلى فهم الميراث. بدون ذلك ، قد تكافح.)

بمعنى آخر ، سيكون كل من Petraeus و Condi و HealthOfficials فصولًا "تنفذ واجهة" - دعنا نسميها IAdvisor الواجهة التي تحتوي فقط على طريقة واحدة: Advise(). لكننا الآن ندخل في التفاصيل.

سيكون هذا مثاليًا

    public class MisterPresident
    {
            // You can pass in any advisor: Condi, HealthOfficials,
            //  Petraeus etc. The president has no idea who it will 
            // be. But he does know that he can ask them to "advise" 
            // and that's all Mr Prez cares for.

        public void RunTheCountry(IAdvisor governmentOfficer)
        {             
            governmentOfficer.Advise();              
        }
    }


    public class USA
    {
        MisterPresident president;

        public USA(MisterPresident president)
        {
            this.president = president;
        }

        public void ImplementPolicy()
        {
            IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
            president.RunTheCountry(governmentOfficer);
        }
    }

ملخص

كل ما تحتاج إلى معرفته حقًا هو:

  • لا يحتاج الرئيس إلى معرفة التفاصيل - تلك التي تركها للآخرين.
  • كل ما يحتاج الرئيس إلى معرفته هو أن يسأل من يسير في الباب لتقديم المشورة له - ونحن نعلم أنهم سيعرفون تمامًا ماذا يفعلون عندما يُطلب منهم تقديم المشورة (لأنهم جميعًا في الواقع أو المستشارين (أو Iadvisors :))

آمل حقًا أن يساعدك. إذا كنت لا تفهم أي شيء نشر تعليقًا وسأحاول مرة أخرى.

تعدد الأشكال هو القدرة على علاج فئة من الكائن كما لو كانت فئة الوالدين.

على سبيل المثال ، لنفترض أن هناك فئة تسمى الحيوانات ، وفئة تسمى الكلب يرث من الحيوانات. تعدد الأشكال هو القدرة على التعامل مع أي كائن كلب ككائن حيوان مثل ذلك:

Dog* dog = new Dog;
Animal* animal = dog;

تعدد الأشكال:

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

ينتج تعدد الأشكال عن حقيقة أن كل فصل يعيش في مساحة اسمه. الأسماء المخصصة في تعريف الفصل لا تتعارض مع أسماء مخصصة في أي مكان خارجه. هذا صحيح كل من متغيرات المثيل في بنية بيانات الكائن وطرق الكائن:

  • مثلما توجد حقول بنية C في مساحة اسم محمية ، لذلك فهي متغيرات مثيل الكائن.

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

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

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

أمثلة:

مثال 1: هنا مثال بسيط مكتوب في بيثون 2.x.

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

مثال 2: يتم تنفيذ تعدد الأشكال في جافا باستخدام الطريقة التحميل الزائد والطريقة تجاوز المفاهيم.

دعونا نفكر في مثال للسيارة لمناقشة تعدد الأشكال. خذ أي علامة تجارية مثل Ford و Honda و Toyota و BMW و Benz وما إلى ذلك ، كل شيء من نوع السيارة.

لكن لكل منها ميزاتها المتقدمة والتكنولوجيا الأكثر تقدماً في سلوكها.

الآن دعونا ننشئ سيارة من النوع الأساسي

car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

دعونا ننفذ مثال سيارة فورد.

يمتد فورد سيارة النوع لروث جميع أعضائها (الخصائص والأساليب).

فورد

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

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

هوندا

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

تمامًا مثل Ford ، تقوم Honda أيضًا بتوسيع نوع السيارة ونفذت طريقة الحركة بطريقتها الخاصة.

الطريقة الغالبة هي ميزة مهمة لتمكين تعدد الأشكال. باستخدام طريقة تجاوز الطريقة ، يمكن للأنواع الفرعية تغيير الطريقة التي تعمل بها الطرق المتوفرة من خلال الميراث.

تعدد الأشكال Example.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

مثال تعدد الأشكال:

في الطريقة الرئيسية لفئة الأشكال المتعددة ، قمت بإنشاء ثلاثة كائنات- سيارة ، فورد وهوندا. تتم إحالة جميع الكائنات الثلاثة بواسطة نوع السيارة.

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

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

ولكن عندما يتعلق الأمر بتنفيذ وقت التشغيل ، يستدعي الجهاز الظاهري الطرق على الكائنات التي هي أنواع فرعية. لذلك ، يتم استدعاء طريقة MOVE () من تطبيقاتها.

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

عادةً ما يشير هذا إلى القدرة على كائن من النوع A للتصرف مثل كائن من النوع B. في البرمجة الموجهة للكائنات ، عادة ما يتم تحقيقها عن طريق الميراث. بعض روابط ويكيبيديا لقراءة المزيد:

تحرير: الروابط المكسورة الثابتة.

تعدد الأشكال هذا:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

يمكنك تمرير كوب فقط بدلاً من مثيل معين. هذا يساعد في العمومية لأنك لست مضطرًا لتقديم مثيل محدد () لكل نوع من أنواع الكوب

أعلم أن هذا سؤال أقدم مع الكثير من الإجابات الجيدة ، لكنني أود تضمين إجابة جملة واحدة:

معالجة نوع مشتق كما لو كان نوع الأساس.

هناك الكثير من الأمثلة المذكورة أعلاه والتي تظهر هذا في العمل ، لكنني أشعر أن هذه إجابة موجزة جيدة.

(كنت أتصفح مقالًا آخر عن شيء مختلف تمامًا .. وظهر تعدد الأشكال ... الآن اعتقدت أنني أعرف ما هو تعدد الأشكال .... ولكن على ما يبدو ليس بهذه الطريقة الجميلة الموضحة .. أراد أن أكتبه في مكان ما .. من الأفضل أن يشاركها ...)

http://www.eioba.com/a/1htn/how-i-explied-rest-to-my-wife

تابع القراءة من هذا الجزء:

..... تعدد الأشكال. هذه طريقة عبقري غريب الأطوار للقول أن الأسماء المختلفة يمكن أن يكون لها نفس الفعل المطبق عليها.

مصطلح تعدد الأشكال من:

بولي = كثير

التشكل = القدرة على التغيير

في البرمجة ، تعدد الأشكال هو "تقنية" تتيح لك "النظر" إلى كائن على أنه أكثر من نوع واحد من الأشياء. على سبيل المثال:

كائن الطالب هو أيضًا كائن شخص. إذا كنت "تنظر" (أي الممثلين) على الطالب ، فربما يمكنك طلب معرف الطالب. لا يمكنك دائمًا القيام بذلك مع شخص ، أليس كذلك؟ (الشخص ليس بالضرورة طالبًا ، وبالتالي قد لا يكون لديه معرف الطالب). ومع ذلك ، ربما يكون لدى الشخص اسم. الطالب يفعل أيضا.

خلاصة القول ، "النظر" في نفس الكائن من "زوايا" مختلفة يمكن أن تمنحك "وجهات نظر مختلفة" (أي خصائص أو طرق مختلفة)

لذلك تتيح لك هذه التقنية بناء أشياء يمكن "النظر إليها" من زوايا مختلفة.

لماذا نستخدم تعدد الأشكال؟ للمبتدئين ... التجريد. في هذه المرحلة يجب أن يكون معلومات كافية :)

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

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

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

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

دعونا نستخدم القياس. لنص موسيقي معين ، كل موسيقي يلعبه يمنحها لمسة خاصة بها في التفسير.

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

إذا كنت مستمعًا للعمل الموسيقي ، فلديك إشارة إلى السيناريو على سبيل المثال "Fuga and Tocata" وكل موسيقي يؤدونه يفعله متعدد الأشكال بطريقتها الخاصة.

هذا مجرد مثال على التصميم المحتمل (في جافا):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}

لقد قدمت نظرة عامة رفيعة المستوى على تعدد الأشكال لسؤال آخر:

تعدد الأشكال في C ++

أتمنى أن يساعد ذلك. مستخلص ...

... يساعد على البدء من اختبار بسيط له وتعريف [تعدد الأشكال]. النظر في الرمز:

Type1 x;
Type2 y;

f(x);
f(y);

هنا، f() هو القيام ببعض العمليات ويتم إعطاؤه القيم x و y كما المدخلات. أن تكون متعددة الأشكال ، f() يجب أن تكون قادرًا على العمل بقيم نوعين متميزين على الأقل (على سبيل المثال int و double) ، إيجاد وتنفيذ رمز نوع مناسب.

(تابع في تعدد الأشكال في C ++ )

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

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

public class PolymorphismExample {

    public static abstract class Vehicle
    {
        public int wheels(){
            return 0;
        }
    }

    public static class Bike extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 2;
        }
    }

    public static class Car extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 4;
        }
    }

    public static class Truck extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 18;
        }
    }

    public static void main(String[] args)
    {
        Vehicle bike = new Bike();
        Vehicle car = new Car();
        Vehicle truck = new Truck();

        System.out.println("Bike has "+bike.wheels()+" wheels");
        System.out.println("Car has "+car.wheels()+" wheels");
        System.out.println("Truck has "+truck.wheels()+" wheels");
    }

}

النتيجه هي:

The Result

لمزيد من المعلومات، يرجى زيارة الموقع https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/polymorphismample.java. اتمني ان يكون مفيدا.

تعدد الأشكال هو قدرة المبرمج على كتابة أساليب تحمل نفس الاسم الذي يقوم بأشياء مختلفة لأنواع مختلفة من الكائنات ، اعتمادًا على احتياجات تلك الكائنات. على سبيل المثال ، إذا كنت تقوم بتطوير فصل يسمى Fraction ودعا فئة ComplexNumber, ، قد يتضمن كلاهما طريقة تسمى display(), ، لكن كل واحد منهم سوف ينفذ هذه الطريقة بشكل مختلف. في PHP ، على سبيل المثال ، يمكنك تنفيذها مثل هذا:

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

المخرجات:

This is a fraction: 1/2
This is a complex number: 1 + 2i

يبدو أن بعض الإجابات الأخرى تشير إلى أن تعدد الأشكال يستخدم فقط بالتزامن مع الميراث ؛ على سبيل المثال ، ربما Fraction و ComplexNumber كلاهما ينفذ فئة مجردة تسمى Number التي لها طريقة display(), ، أي الكسر والرقم المعقد هو كلاهما ملزم بالتنفيذ. لكنك لا تفعل ذلك بحاجة إلى الميراث للاستفادة من تعدد الأشكال.

على الأقل في اللغات المغطاة ديناميكيًا مثل PHP (لا أعرف عن C ++ أو Java) ، يتيح تعدد الأشكال للمطور استدعاء طريقة دون معرفة نوع الكائن بالضرورة في وقت مبكر ، والثقة في أن التنفيذ الصحيح للطريقة يدعى يسمى. على سبيل المثال ، قل أن المستخدم يختار نوع Number خلقت:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

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

تعدد الأشكال حرفيا ، أشكال متعددة. (أو العديد من النماذج): كائن من فئات مختلفة وطريقة الاسم نفسه ، ولكن سير العمل مختلف. مثال بسيط هو:

النظر في شخص X.

إنه شخص واحد فقط لكنه يتصرف بأكبر عدد ممكن. قد تسأل كيف:

إنه ابن لأمه. صديق لأصدقائه. أخ لأخته.

تعدد الأشكال في OOP يعني أن الطبقة يمكن أن يكون لها أنواع مختلفة ، والميراث هو إحدى طرق تنفيذ تعدد الأشكال.

فمثلا، شكل هي واجهة ، لديها ميدان, دائرة, الماس الأنواع الفرعية. الآن لديك كائن مربع ، يمكنك وضع المربع لتشكيله تلقائيًا ، لأن Square هو شكل. ولكن عندما تحاول الانزلاق إلى المربع ، يجب أن تقوم بعمل صريح صريح ، لأنه لا يمكنك القول أن الشكل مربع ، فقد يكون هذا الدائرة أيضًا. لذلك تحتاج إلى إلقاءها يدويًا برمز مثل Square s = (Square)shape, ، ماذا لو كان الشكل دائرة ، سوف تحصل java.lang.ClassCastException, ، لأن الدائرة ليست مربعة.

تعدد الأشكال:

تنفيذ مختلف وفقًا لمثيل الفئة ، وليس نوع المتغير المرجعي.

يمكن أن يشير متغير مرجع نوع الواجهة إلى أي من مثيلات الفئة التي تنفذ تلك الواجهة.

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

تذكر أنه يجب حفظ كل فئة في ملفات منفصلة.

يوضح الرمز التالي تعدد الأشكال:

الفئة الفائقة:

public class Parent {
    //Define things that all classes share
    String maidenName;
    String familyTree;

    //Give the top class a default method
    public void speak(){
         System.out.println("We are all Parents");
    }
}

الأب ، فئة فرعية:

public class Father extends Parent{
    //Can use maidenName and familyTree here
    String name="Joe";
    String called="dad";

    //Give the top class a default method
    public void speak(){
        System.out.println("I am "+name+", the father.");
    }
}

الطفل ، فئة فرعية أخرى:

public class Child extends Father {
    //Can use maidenName, familyTree, called and name here

    //Give the top class a default method
    public void speak(){
        System.out.println("Hi "+called+". What are we going to do today?");
    }
}

طريقة التنفيذ ، مراجع فئة الوالدين للبدء:

public class Parenting{
    public static void main(String[] args) {
        Parent parents = new Parent();
        Parent parent = new Father();
        Parent child = new Child();

        parents.speak();
        parent.speak();
        child.speak();
    }
}

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

أتمنى أن يساعد هذا ويوضح ذلك. سأقوم بنشر النتائج عندما أجد جهاز كمبيوتر يمكنني استخدامه للتحقق من الرمز. شكرا على الصبر!

يعدد الأشكال نفس الروتين (الوظيفة ، الطريقة) بالعمل على أنواع مختلفة.

نظرًا لأن العديد من الإجابات الحالية تخلط بين الأشكال المتعددة ، فهناك ثلاث طرق (بما في ذلك النوع الفرعي) لتنفيذ تعدد الأشكال.

  • تعدد الأشكال المعلمة (عامة) يسمح لروتين بقبول معلمات نوع أو أكثر ، بالإضافة إلى المعلمات العادية ، ويعمل على هذه الأنواع.
  • تعدد الأشكال من النوع الفرعي يسمح لروتين بالعمل على أي نوع فرعي من معلماته.
  • تعدد الأشكال المخصصة يستخدم بشكل عام التحميل الروتيني لمنح السلوك متعدد الأشكال ، ولكن يمكن أن يشير إلى تطبيقات الأشكال الأخرى أيضًا.

أنظر أيضا:

http://wiki.c2.com/؟categorypolymorphism

https://en.wikipedia.org/wiki/polymorphism_(computer_science)

في اللغات الموجهة نحو الكائن ، يتيح تعدد الأشكال العلاج والتعامل مع أنواع البيانات المختلفة من خلال نفس الواجهة. على سبيل المثال ، النظر في الميراث في C ++: يمكن استخدام الفئة B من الفئة A. مؤشر من النوع A* (المؤشر إلى الفئة A) يمكن استخدامه للتعامل مع كائن من الفئة A وكائن من الفئة B.

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

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

باستخدام تعدد الأشكال ، لا تعتمد وحدة المستوى العالي على وحدة منخفضة المستوى. كلاهما يعتمد على التجريدات. هذا يساعدنا على تطبيق مبدأ انعكاس التبعية (https://en.wikipedia.org/wiki/dependency_inversion_principle).

هذا هو المكان الذي وجدت فيه التعريف أعلاه. بعد حوالي 50 دقيقة من الفيديو ، يشرح المدرب ما سبق.https://www.youtube.com/watch؟v=tmuno5rznee

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top