سؤال

...أو هم نفس الشيء ؟ أنا لاحظت أن كل لديها قناعاتها ويكيبيديا: تعدد الأشكال, متعددة الإرسال, لكن أواجه مشكلة في رؤية كيف أن المفاهيم تختلف.

تحرير: و كيف الحمولة الزائدة تناسب كل هذا ؟

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

المحلول

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

عدد من المعلمات المستخدمة من قبل اللغة/وقت التشغيل يحدد نوع ' تعدد الأشكال التي تدعمها لغة.

واحد الإرسال هو نوع من تعدد الأشكال حيث معلمة واحدة فقط يستخدم (مستقبل الرسالة - this, أو self) لتحديد الدعوة.

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

لذلك يمكن القول أن تعدد الأشكال هو مصطلح عام و متعددة و واحد الإرسال هي أنواع محددة من تعدد الأشكال.

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

نموذج التعليمات البرمجية:

using NUnit.Framework;

namespace SanityCheck.UnitTests.StackOverflow
{
    [TestFixture]
    public class DispatchTypes
    {
        [Test]
        public void Polymorphism()
        {
            Baz baz = new Baz();
            Foo foo = new Foo();

            // overloading - parameter type is known during compile time
            Assert.AreEqual("zap object", baz.Zap("hello"));
            Assert.AreEqual("zap foo", baz.Zap(foo));


            // virtual call - single dispatch. Baz is used.
            Zapper zapper = baz;
            Assert.AreEqual("zap object", zapper.Zap("hello"));
            Assert.AreEqual("zap foo", zapper.Zap(foo));


            // C# has doesn't support multiple dispatch so it doesn't
            // know that oFoo is actually of type Foo.
            //
            // In languages with multiple dispatch, the type of oFoo will 
            // also be used in runtime so Baz.Zap(Foo) will be called
            // instead of Baz.Zap(object)
            object oFoo = foo;
            Assert.AreEqual("zap object", zapper.Zap(oFoo));
        }

        public class Zapper
        {
            public virtual string Zap(object o) { return "generic zapper" ; }
            public virtual string Zap(Foo f) { return "generic zapper"; }
        }

        public class Baz : Zapper
        {
            public override string Zap(object o) { return "zap object"; }
            public override string Zap(Foo f) { return "zap foo"; }
        }

        public class Foo { }
    }
}

نصائح أخرى

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

متعددة الإرسال يسمح subtyping تعدد الأشكال من الحجج طريقة المكالمات.

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

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

لم أسمع متعددة الإرسال من قبل ولكن بعد نظرة عابرة على صفحة ويكيبيديا يبدو الكثير مثل MD هو نوع من تعدد الأشكال, عندما تستخدم مع الحجج إلى أسلوب.

تعدد الأشكال هي في الأساس مفهوم كائن يمكن اعتبار أي نوع هو قاعدة.حتى إذا كان لديك Car و Truck, أنهم على حد سواء يمكن أن ينظر إليه باعتباره Vehicle.هذا يعني أنك يمكن أن ندعو أي Vehicle طريقة إما واحد.

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

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

هذا يمكن أن يكون جميلا لو Start() طريقة اللازمة ليتم استدعاؤها مع مختلف الحجج.ربما Car.Start(Key carKey) مقابل Missile.Start(int launchCode)

ولكن على حد سواء يمكن أن يسمى StartObject(theCar) أو StartObject(theMissile)

مفهوم مثير للاهتمام...

متعددة الإرسال هو أقرب إلى وظيفة الحمولة الزائدة (كما رأينا في Java/C++) ، باستثناء وظيفة الاحتجاج يعتمد على وقت تشغيل نوع من الحجج ، وليس على نوع ثابت.

إذا كنت تريد المفاهيمي أي ما يعادل استدعاء الأسلوب

(obj_1, obj_2, ..., obj_n)->method

تعتمد على كل نوع في المجموعة ، ثم تريد متعددة الإرسال.تعدد الأشكال يتوافق مع الحالة n=1 و هو سمة ضرورية من OOP.

متعددة الإرسال هو نوع من تعدد الأشكال.في Java/C#/C++, هناك تعدد الأشكال من خلال الميراث الغالب ، ولكن هذا ليس متعددة الإرسال ، والتي تقوم على اثنين أو أكثر من الحجج (وليس فقط this, مثل Java/C#/C++)

متعددة الإرسال تعتمد على تعدد الأشكال القائمة.نموذجية تعدد الأشكال التي واجهتها في C++, C# ، VB.NET, الخ...يستخدم واحد-أي الإرسالالدالة التي يحصل تسمى يعتمد فقط على فئة واحدة على سبيل المثال.متعددة الإرسال يعتمد على عدة مثيلات الفئة.

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