سؤال

لدي قاعدة مجردة من الدرجة وأريد أن تعلن حقل أو الممتلكات التي سيكون لها قيمة مختلفة في كل فئة أن يرث من هذه الفئة الأصل.

أريد تعريف في baseclass حتى أتمكن من الرجوع في قاعدة الطبقة الطريقة - على سبيل المثال الأسمى ToString أن أقول "هذا الكائن هو من نوع الملكية/حقل".لدي ثلاث طرق أستطيع أن أرى من يفعل هذا, ولكن أنا أتساءل ما هو أفضل أو قبول طريقة لفعل هذا ؟ مبتدئ السؤال, آسف.

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

abstract class Father
{
    abstract public int MyInt { get; set;}
}

class Son : Father
{
    public override int MyInt
    {
        get { return 1; }
        set { }
    }
}

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

abstract class Mother
{
    public int MyInt = 0;
}

class Daughter : Mother
{
    public int MyInt = 1;
}

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

abstract class Aunt
{
    protected int MyInt;
}

class Niece : Aunt
{
    public Niece()
    {
        MyInt = 1;
    }
}

انها قليلا من نظرية السؤال و أعتقد أن الجواب يجب أن يكون الخيار 1 كما هو فقط آمنة الخيار ولكن أنا مجرد الحصول على السيطرة مع C# و أريد أن أطلب هذا من الناس مع المزيد من الخبرة.

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

المحلول

من ثلاثة حلول فقط الخيار 1 هو متعددة الأشكال.

الحقول في حد ذاتها لا يمكن تجاوزها.وهو بالضبط لماذا الخيار 2 ترجع جديد كلمة تحذير.

حل التحذير ليس إلحاق "الجديد" الكلمة ، ولكن لتنفيذ الخيار 1.

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

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

هذا هو كيف حقا متعددة الأشكال تنفيذ الممتلكات الخاصة بك قد تبدو ، مما يتيح الفئات المشتقة في التحكم.

abstract class Parent
{
    abstract public int MyInt { get; }
}

class Father : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "X" and return a value */ }
    }
}

class Mother : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "Y" and return a value */ }
    }
}

نصائح أخرى

الخيار 2 هو غير كاتب - لا يمكنك تجاوز الحقول, يمكنك فقط إخفاء لهم.

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

abstract class Mother
{
    private readonly int myInt;
    public int MyInt { get { return myInt; } }

    protected Mother(int myInt)
    {
        this.myInt = myInt;
    }
}

class Daughter : Mother
{
    public Daughter() : base(1)
    {
    }
}

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

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

شخصيا, أعتقد أن أفضل خيار هو 3;لأنه يوفر واضحة مركزية قيمة يمكن الرجوع إليها داخليا من قبل الأطفال دون مشاحنات من تحديد المجالات الخاصة بهم -- الذي هو مشكلة مع الخيار 1.

يمكنك تحديد شيء من هذا القبيل:

abstract class Father
{
    //Do you need it public?
    protected readonly int MyInt;
}

class Son : Father
{
    public Son()
    {
        MyInt = 1;
    }
}

من خلال تحديد قيمة للقراءة فقط ، فإنه يضمن قيمة تلك الفئة لا تزال دون تغيير عن عمر من وجوه.

أعتقد أن السؤال التالي هو:لماذا كنت في حاجة إليها ؟

هل يمكن أن تفعل هذا

class x
{
    private int _myInt;
    public virtual int myInt { get { return _myInt; } set { _myInt = value; } }
}

class y : x
{
    private int _myYInt;
    public override int myInt { get { return _myYInt; } set { _myYInt = value; } }
}

الظاهري يتيح لك الحصول على موقع على الجسم أن يفعل شيئا و لا يزال يتيح الفئات الفرعية تجاوز ذلك.

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

باستخدام المثال أعلاه:

//you may want to also use interfaces.
interface IFather
{
    int MyInt { get; set; }
}


public class Father : IFather
{
    //defaulting the value of this property to 1
    private int myInt = 1;

    public virtual int MyInt
    {
        get { return myInt; }
        set { myInt = value; }
    }
}

public class Son : Father
{
    public override int MyInt
    {
        get {

            //demonstrating that you can access base.properties
            //this will return 1 from the base class
            int baseInt = base.MyInt;

            //add 1 and return new value
            return baseInt + 1;
        }
        set
        {
            //sets the value of the property
            base.MyInt = value;
        }
    }
}

في برنامج:

Son son = new Son();
//son.MyInt will equal 2

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

abstract class Base 
{
 protected int myInt;
 protected abstract void setMyInt();
}

class Derived : Base 
{
 override protected void setMyInt()
 {
   myInt = 3;
 }
}

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

abstract class Father
{
    abstract public int MyInt { get; }
}

class Son : Father
{
    public override int MyInt
    {
        get { return 1; }
    }
}

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

abstract class Aunt
{
    protected int MyInt;
    protected Aunt(int myInt)
    {
        MyInt = myInt;
    }

}

بالطبع, ثم لا يزال لديك خيار لجعل حقل خاص ثم حسب الحاجة ، وفضح المحمية أو الممتلكات العامة حاصل.

أنا فعلت هذا...

namespace Core.Text.Menus
{
    public abstract class AbstractBaseClass
    {
        public string SELECT_MODEL;
        public string BROWSE_RECORDS;
        public string SETUP;
    }
}

namespace Core.Text.Menus
{
    public class English : AbstractBaseClass
    {
        public English()
        {
            base.SELECT_MODEL = "Select Model";
            base.BROWSE_RECORDS = "Browse Measurements";
            base.SETUP = "Setup Instrument";
        }
    }
}

هذا الطريق لا يزال يمكنك استخدام الحقول.

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