Подклассы, НВИ


Если следующее считать код ВТФ?

abstract class BaseCat
{
    public virtual void SayMiau()
    {
        Console.WriteLine("MIAU!");
    }
}

class StrangeCat : BaseCat
{
    private readonly bool _canMiau;

    public StrangeCat(bool canMiau)
    {
        _canMiau = canMiau;
    }

    public override void SayMiau()
    {
        if (_canMiau)
        {
            base.SayMiau();
        }
    }
}

Что правильный подход здесь? Не-виртуальные интерфейсы (НВИ)?



215
3
задан 29 июля 2011 в 07:07 Источник Поделиться
Комментарии
2 ответа

Пример вы показываете не имеет никакого обоснования BaseCat будучи абстрактным, делает им non-абстрактные и ваш пример имеет смысл. Хотя я бы убедительные доказательства того, что ваш BaseCat может потребоваться реализовать структуру StrangeCat. Затем StrangeCat просто реализовать изменение _canMiau если действительное.

public class BaseCat
{
protected bool _canMiau;

// if you wanted abstract so BaseCat could not be constructed make the constructor protected
protected BaseCat(bool canMiau) { _canMiau = canMiau; }

public virtual void SayMiau()
{
if (_canMiau)
{
Console.WriteLine("MIAU!");
}
}
}

public class StrangeCat : BaseCat
{
public StrangeCat(bool canMiau) : base(canMiau) { }
}

public class MuteCat : BaseCat
{
public MuteCat() : base(false) { }
}

public class LoudCat : BaseCat
{
public LoudCat() : base(true) { }
}

Затем, когда вы пинаете кошку, он будет реагировать соответствующим образом с минимальным дублированием логики. Я хотел бы избежать абстрактный класс, если наследники намерены реализовать существенные логические различия, ваш пример не показывает, что (хотя твое реальное положение дел может еще что).

public void KickCat(BaseCat)
{
Foot.StraightTowardsCat(BaseCat, Anatomy.Rear);
BaseCat.SayMiau();
}

...

KickCat(new MuteCat()); // I love this cat, it's like it doesn't even care!
KickCat(new LoudCat()); // Whines, blah.
KickCat(new StrangeCat(true)); // Whines this time.
KickCat(new StrangeCat(false)); // Doesn't whine this time! Woot!

2
ответ дан 29 июля 2011 в 02:07 Источник Поделиться

Да, надо.
Это нарушает принцип подстановки Лисков.

Я не знаю, что это НВИ, но я думаю, что правильный подход в данном случае будет
чтобы создать NormalCat подклассов: BaseCat и переместить метод SayMiau() для этого класса.

1
ответ дан 29 июля 2011 в 10:07 Источник Поделиться