سؤال

كيف تعلن الأسلوب في C# التي ينبغي تجاوزها (أو للتجاوز) قبل dereived الدرجة وربما حتى خارج الجمعية - ولكن ينبغي أن يكون ضامنا إلا من داخل الفعلي الصف ؟

(أيمثل الافتراضي الخاص وظيفة في C++)

[عدل]
private virtual هو بالضبط ما كنت تنوي:"هنا وسيلة لتعديل سلوك بلدي ، ولكن كنت لا تزال لا يسمح استدعاء هذه الدالة مباشرة (لأن الدعوة فإنه يتطلب غامضة الدعاء فقط بلدي قاعدة الطبقة لا)"

وذلك لتوضيح ذلك:ما هو أفضل تعبير عن ذلك في C# ؟

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

المحلول

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

شيء لا يساعد هنا هو أن C++ لا تتطلب تكرار الكلمة الافتراضية.المؤدية إلى الصعب عكس مهندس أسرار مثل هذا واحد:

#include "stdafx.h"
#include <iostream>

class Base {
private:
    virtual void Method() = 0;
public:
    void Test() {
        Method();
    }
};
class Derived : public Base {
private:
    void Method() { std::cout << "Who the heck called me?"; }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* p = new Derived;
    p->Test();
}

أنا أتفق هناك احتمال وجود دور القطاع الخاص في الميراث.لغة C# المصممين قلت لا!على الرغم من.

نصائح أخرى

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

عضو خاص غير مرئي إلى الطبقات الطفل.أعتقد المحمية الظاهري سوف تؤدي طريقة تريد ؟

تحديث:

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

public abstract class Animal
{
    public void DisplayAttributes()
    {
        Console.WriteLine(Header());
        Console.WriteLine("Name: " + Name());
        Console.WriteLine("Legs: " + Legs());
        Console.WriteLine();
    }

    protected virtual int Legs()
    {
        return 4;
    }

    private string Header()
    {
        return "Displaying Animal Attributes";
    }

    protected abstract string Name();
}

public class Bird : Animal
{
    protected override string Name()
    {
        return "Bird";
    }

    protected override int Legs()
    {
        return 2;
    }
}

public class Zebra : Animal
{
    protected override string Name()
    {
        return "Zebra";
    }
}

public class Fish : Animal
{
    protected override string Name()
    {
        return "Fish";
    }

    protected override int Legs()
    {
        return 0;
    }

    private string Header()
    {
        return "Displaying Fish Attributes";
    }

    protected virtual int Gils()
    {
        return 2;
    }

    public new void DisplayAttributes()
    {
        Console.WriteLine(Header());
        Console.WriteLine("Name: " + Name());
        Console.WriteLine("Gils: " + Gils());
        Console.WriteLine();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Bird bird = new Bird();
        bird.DisplayAttributes();
        //Displaying Animal Attributes
        //Name: Bird
        //Legs: 2

        Zebra zebra = new Zebra();
        zebra.DisplayAttributes();
        //Displaying Animal Attributes
        //Name: Zebra
        //Legs: 4


        Fish fish = new Fish();
        fish.DisplayAttributes();
        //Displaying Fish Attributes
        //Name: Fish
        //Gils: 2

        List<Animal> animalCollection = new List<Animal>();
        animalCollection.Add(bird);
        animalCollection.Add(zebra);
        animalCollection.Add(fish);

        foreach (Animal animal in animalCollection)
        {
            animal.DisplayAttributes();
            //Displaying Animal Attributes
            //Name: Bird
            //Legs: 2

            //Displaying Animal Attributes
            //Name: Zebra
            //Legs: 4

            //Displaying Animal Attributes
            //Name: Fish
            //Legs: 0
            //*Note the difference here
            //Inheritted member cannot override the
            //base class functionality of a non-virtual member
        }
    }
}

في هذا المثال, الطيور, حمار الوحش, والأسماك يمكن أن نطلق اسمها والساقين الطرق ، ولكن في سياق إذا كان هذا المثال ، هناك لن يكون بالضرورة فائدة في القيام بذلك.بالإضافة إلى ذلك, كما هو موضح من قبل الأسماك ، DisplayAttributes() يمكن تعديلها ل مثيل ملموسة مستمدة الطبقة ؛ ولكن عندما كنت تبحث في الحيوان كما في حلقة foreach ، يمكنك الحصول على قاعدة الطبقات DisplayAttributes السلوك بغض النظر عن الفعلية نوع من الحيوانات.آمل أن يكون هذا قد يساعد povide نوع من وظيفة كنت ترغب في تكرار.

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

هنا مثال على ما vboctor وقد سبق ذكره:

public class Base
{
    private Func<Base, int> func;
    protected void SetFunc(Func<Base, int> func)
    {
        this.func = func;
    }

    private void CallFunc()
    {
        if (func != null)
        {
            var i = func(this);
        }
    }
}

public class Sub : Base
{
    private void DoFuncyStuff()
    {
         this.SetFunc(b => 42);
    }
}

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

كما قرأت السؤال: هل يمكن أن يعني أمرين.

أولا ,إذا كنت تريد وظيفة في الدرجة التي يمكن أن تنقضها في الفئة B ولكن غير مرئية إلى أي الطبقة الخارجية:

public class ClassA
{
  protected virtual ReturnType FunctionName(...) { ... }
}

public class ClassB
{
  protected override ReturnType FunctionName(...) { ... }
}

ثانيا ، إذا كنت ترغب في فرض تنفيذ الطبقة تعريف الدالة:

public abstract class ClassA
{
  protected abstract ReturnType FunctionName(...);
}

public class ClassB
{
  protected override ReturnType FunctionName(...) { ... }
}

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

الملف 1:

public partial class ClassA
{
    private ReturnType FunctionName(...);
}  

ملف 2:

public partial class ClassA
{
  //actual implimentation
  private ReturnType FunctionName(...){ ... }; 
}

جزئيات لا تستخدم على نطاق واسع إلا عند التعامل مع تصميم الملفات التي تم إنشاؤها مثل Linq2Sql الملفات أو التنظيم الإداري ، أو WinForms ، إلخ.

أعتقد أن هذا لن ينجح كما تعتزم ولكن اسمحوا لي أن رسم بعض الزائفة رمز بالنسبة لك:

public interface BaseClassFunction {
    void PleaseCallMe();
}

public class BaseClass {
    private BaseClassFunction fn;
    public BaseClass(BaseClassFunction fn) {
        this.fn = fn;
    }
    private CallMe() {
        fn.PleaseCallMe();
    }
    public PublicCallMe() {
        CallMe();
    }
}

private class DerivedClassFunction : BaseClassFunction {
    void PleaseCallMe() { ... do something important ... }
}

public class DerivedClassFunction {
    public DerivedClassFunction() : BaseClass(new DerivedClassFunction()) {
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top