Наследование классов, заставляя новые классы реализовывать определенные функции - PullRequest
5 голосов
/ 04 октября 2011

Хорошо, так что я возился с несколькими вещами, в частности, с интерфейсами.

Скажем, у меня есть класс 'Cat' с его базой, поскольку 'Animal' Animal имеет метод, подобный этому

public virtual void Walk()
{
    // Do walking stuff
}

Так что Cat переопределит это с помощью:

public override void Walk()
{
    // Do cat specific walking stuff
}

Простое право?

Вот мой вопрос, есть ли способ заставить cat переопределить базовую Walk ()?метод?Так что, если бы другой разработчик добавил класс Dog, он был бы вынужден реализовать свой собственный метод Walk (даже если он был просто base.Walk ())?

Так что интерфейсы вроде бы решают это, вот что япробовал

Cat: Animal: Interface Animal должен реализовывать метод Walk, но Cat не

Cat: Animal, Interface Cat должен реализовывать метод Walk, но если разработчик этого не делаетЕсли вы не добавите или забудете «Интерфейс», тогда он «сломает» его.

Может ли кто-нибудь дать мне указатель, как это сделать?

Спасибо.

Edit 1

Вот то, к чему я стремлюсь, надеюсь, это прояснит ситуацию.

public class Animal
{
    public Animal()
    {
        Console.WriteLine("Animal");
    }

    public virtual void Walk()
    {

    }
}

public class Cat : Animal
{
    public Cat() : base()
    {
        Console.WriteLine("Cat");
    }

    public override void Walk()
    { 

    }
}

class Dog : Animal
{

    public Dog()
    {

    }

    public override void Walk()
    {
        // Dog implementation 
        // and / or calls base method
        base.Walk();
    }
}

Это приведет к ошибке

class Dog : Animal
{

    public Dog()
    {

    }
}

1 Ответ

17 голосов
/ 04 октября 2011

Это когда вы хотите пометить базовый класс и базовый метод как abstract.

abstract class Animal 
{
    public abstract void Walk(); 
}

Производные классы должны будут реализовывать Walk для создания экземпляров.

class Cat : Animal 
{
    public override void Walk() { }
}

Примечание: это изменение делает Animal неинстанцируемым само по себе, все ссылки на него будут через более производные классы.

Animal animal = new Cat();

Вот мой вопрос, есть ли способ заставить кота переопределить базовый метод Walk ()? Так что, если другой разработчик добавил класс Dog, они будет вынужден реализовать свой собственный метод Walk (даже если это было просто base.Walk ()) ?

Здесь у вас есть разъединение или противоположные цели. Чтобы заставить детей реализовать метод, вы помечаете его как абстрактный. Чтобы ребенок мог выбрать использование базовой реализации, он должен быть виртуальным, что затем сделает его необязательным для переопределения. Даже если вам нужно было в основном использовать шаблонный шаблонный шаблон и сделать абстрактным частей алгоритма, чтобы перенести реализацию в более низкие классы, проблема остается той же: вы не можете принудительно переопределить, оставляя также реализацию по умолчанию. *

Вам необходимо определить, хотите ли вы иметь базовую реализацию, частично или полностью.


* Теоретически у вас должно быть abstract void Walk(); protected void WalkImpl() { } в базе, что позволило бы детям выбирать WalkImpl, если они не хотят предоставлять свою собственную реализацию.

class Cat : Animal
{
     protected override void Walk() { base.WalkImpl(); }
}

Однако я не уверен, что я чувствую по этому поводу. Вы в основном усложняете жизнь авторов производных классов, форсируя переопределение, в то же время позволяя им использовать поведение по умолчанию. Если можно использовать поведение по умолчанию, просто перейдите с virtual и доверьте авторам производных классов переопределение, когда они считают, что это уместно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...