Patrick Skelton Ответов: 1

Изо всех сил пытаясь понять интерфейсы и абстрактные базовые классы


Несмотря на то, что у меня болит голова от прочитанного, я изо всех сил пытаюсь понять, что именно не так со следующим:

public interface IAnimal
{
    int Age();
    int NumLegs();
}

public interface IBird : IAnimal
{
    bool CanFly();
}

public interface IMammal : IAnimal
{
    int RunningSpeed();
}

public abstract class AnimalBase : IAnimal
{
    public abstract int Age();
    public abstract void PrintAge();
    public override int NumLegs() { return 4; } // Error!
};

public class Sparrow : AnimalBase, IBird
{
    public override void PrintAge() { Console.WriteLine( $"Sparrow is {Age()} years old." ); }

    public override bool CanFly() { return true; } // Error!

    public override int Age() { return 3; }
}


У меня есть пара ошибок (до сих пор):

В моем классе AnimalBase, Я получаю сообщение об ошибке "AnimalBase.NumLegs() - не найден подходящий метод для переопределения". Почему? AnimalBase инвентарь IAnimal так почему же он не может видеть объявление метода в интерфейсе?

И почему абстрактное Age() в AnimalBase ладно? Я предполагаю, что здесь я просто объявляю совершенно новый метод, который не имеет ничего общего с объявлением в интерфейсе, но разве я не должен получить какое-то предупреждение о том, что я как бы "скрываю" объявление интерфейса?

Вторая ошибка-точно такой же "Воробей".CanFly () - не найден подходящий метод для переопределения'. Опять же, почему? Sparrow инвентарь IBird- так почему же он не видит IBird.CanFly()?

Любая помощь в понимании этого может спасти мои оставшиеся волосы.

Что я уже пробовал:

Я читал и читал, и я нашел много примеров, которые действительно работают, но не объясняют, почему то, что я пытаюсь сделать, очевидно, неправильно.

1 Ответов

Рейтинг:
12

OriginalGriff

Ну, ваш абстрактный класс объявляет override член NumLegs - который не имеет реализации базового класса для переопределения. Что вам нужно, так это объявить его как virtual что позволяет производным классам переопределять его:

public virtual int NumLegs() { return 4; } 
Если они это сделают, то будет вызвана "новая" версия, если нет, то будет использована версия базового класса и будет возвращено 4.

Та же проблема существует и с CanFly: интерфейсные методы не могут быть переопределены, поскольку они не имеют реализации базового класса для переопределения. В этом случае просто удалите ключевое слово:
public bool CanFly() { return true; } 

и ваши ошибки исчезнут.


Patrick Skelton

Арррггххххххххххх ... думаю, мой мозг уже раскололся на Рождество. Это так удручающе очевидно теперь, когда вы объяснили это. Спасибо!

OriginalGriff

Пожалуйста!