ما الفرق بين فئة مجردة، وفئة مع منشئين محميين فقط؟ (.صافي)

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

سؤال

ما هو الفرق بين فئة مجردة، وفئة مع منشئ (منشئ) محمي فقط؟ يبدو أنهم يشبهون لي إلى حد ما، لأنه لا يمكنك إنشاء إلاهي واحد.

تعديل:

كيف يمكنك إنشاء مثيل في فئة مشتقة، مع فئة أساسية مع منشئ محمي؟ على سبيل المثال:

public class ProtectedConstructor
{
    protected ProtectedConstructor()
    {

    }

    public static ProtectedConstructor GetInstance()
    {
        return new ProtectedConstructor(); // this is fine
    }
}

public class DerivedClass : ProtectedConstructor
{

    public void createInstance()
    {
        ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
    }

    public static ProtectedConstructor getInstance()
    {
        return new ProtectedConstructor(); // doesn't compile

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

المحلول

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

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

يحرر:

إذا اتصلت ProtectedConstructor.GetInstance(); بدلا من new ProtectedConstructor();, ، إنها تعمل. ربما لا يمكن استدعاء البناة المحمية بهذه الطريقة؟ ولكن الأساليب المحمية بالتأكيد يمكن.

هنا هي مقالة مثيرة للاهتمام حول هذا الموضوع.

نصائح أخرى

في معظم الأحيان، هناك اختلاف عملي قليل، حيث أن كلاهما قادران فقط على إنشاء من خلال فئة فرعية.

ومع ذلك، بمناسبة الفصل abstract لديه فوائدان:

  1. مع منشئين محميين، ما زال من الممكن إنشاء مثيل للفئة بطريقتين. يمكنك استخدام Activator.CreateInstance. مع BindingFlags.nonpublic، أو يمكنك استخدام طريقة المصنع المحددة في الفصل (أو الفئة الفرعية) لإنشاء مثيل للفئة. ومع ذلك، لا يمكن إنشاء ملخص ملحوظ في الفصل.

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

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

يمكن أن يكون للفئة مجردة طرق مجردة؛ الأساليب التي تتكون فقط من توقيع الطريقة، ولكن لا يوجد جسم، أن الفصول للأطفال يجب ينفذ.

على محمل الجد، لم يذكر شخص واحد حتى الآن؟

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

public class ProtectedConstructor
{
    protected ProtectedConstructor(string arg)
    {
        // do something with arg
    }

    public static ProtectedConstructor GetInstance()
    {
        return new ProtectedConstructor("test"); 
    }
} 

public class DerivedClass : ProtectedConstructor
{
    protected DerivedClass(string arg) : base(arg)
    {
    }

    public void createInstance()
    {
        DerivedClass p = new DerivedClass("test"); 
    }

    public static DerivedClass getInstance()
    {
        return new DerivedClass("test"); 
    }
}

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

public abstract Thread
{
    protected Thread()
    {
    }

    public void Run()
    {
        LogStart();
        DoRun();
        LogEnd();
    }

    protected abstract DoRun();

    private void LogStart()
    {
         Console.Write("Starting Thread Run");
    }

    private void LogEnd()
    {
         Console.Write("Ending Thread Run");
    }
}


public class HelloWorldThread : Thread
{
    public HelloWorldThread()
    {
    }

    protected override DoRun()
    {
        Console.Write("Hello World");
    }
}

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

لمنع الآخرين من صنع هذه الأنواع من التغييرات، يمكنك التعليق على التعليمات البرمجية الخاصة بك. أو، كما قال آخرون، استخدم "مجردة" للوثيقة صراحة نيتكتك.

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

مثال شائع على هذا قد يكون مثل نمط Singleton: http://en.wikipedia.org/wiki/singleton_pattern.

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


public abstract class Parent
{
  protected abstract void AMethod();
}

public abstract class Child: Parent
{
  // does not implement AMethod, and that's ok
}

public class Child2: Parent
{
  // does not implement AMethod, and that will cause a compile error
}

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

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