Принимая во внимание принятый ответ здесь , идея общих рекомендаций заключается в том, что, где это возможно, предпочтение определению классов перед интерфейсами.
Рассмотрим следующий дизайн:
- Базовый класс
ChessPiece
, для которого также определены несколько дочерних классов
- Некоторым типам фигур требуется запись, если они уже были перемещены (а именно
Pawn
, Rook
, King
): свойство bool HasMoved
- Тип фигуры, который как
King
, не может быть захвачен ; все остальное может быть: bool IsCaptured
свойство
Проблема заключается в конфликте между # 2 и 3 (нет проблем, если я реализую только один из двух) из-за производного класса King
, который распространен в # 2 и 3.
В идеале должны быть реализованы оба абстрактных класса CapturablePiece
и MoveRecordedPiece
, которые оба наследуют от ChessPiece
. Но C # не допускает множественное наследование классов , и именно здесь вступают интерфейсы.
Если интерфейсы были реализованы, теперь все конкретные дочерние классы могут вручную реализовать каждое обязательное свойство. Рассмотрим этот пример:
// needed type-check
ChessPiece piece;
// some calculations...
if (piece is ICapturablePiece) // or using the 'as' keyword
//or...
if (piece is IMoveRecordedPiece)
// which in the case of non-conflicting abstract classes,
// this is easily doable and valid because of
// inheritance to the base class
Я не могу сделать это, так как интерфейсы как есть. Он не может наследовать от чего-либо , это просто автономный маркер для методов, которые должны быть реализованы.
Версии абстрактного класса по-прежнему предпочтительнее - CapturablePiece
и MoveRecordedPiece
, поскольку его базовый тип - ChessPiece
, и я уверен, что эта логика - " is-an " вместо « can-do » (как указано в ссылке выше).
Мой вопрос теперь будет: Как бы я мог улучшить дизайн , учитывая:
- Тот факт, что вы не можете наследовать несколько классов, а интерфейсы не могут ничего наследовать.
- Преимущество абстрактных классов над интерфейсами
- Блок кода, где требуется проверка типа
EDIT:
Это не дубликат связанного вопроса. Это о том, как улучшить дизайн с учетом интерфейсов и абстрактных классов.