Строить новую иерархию, использовать абстрактный класс или интерфейс? - PullRequest
0 голосов
/ 22 июня 2009

Я готовлюсь построить граф сцены 2D для своей игры, и я хотел бы знать, должен ли я использовать в его корне интерфейс или два или несколько абстрактных классов. Вот мои требования:

  • Элемент базового узла
    • нужно уметь хранить матрицу
    • также должен иметь возможность хранить список дочерних узлов
    • а также один родительский узел
  • Преобразование элементов узла
    • должен иметь метод Draw (очень вероятно, что реализация будет такой же)
    • требует, чтобы элемент базового узла был реализовано / получено из
  • Элемент рисованного узла
    • должен иметь метод Draw (реализация может отличаться)
    • требует, чтобы элемент базового узла был реализованы / получены и не могут быть реализованы / получены из элемент узла преобразования

Какую схему базовых классов / интерфейсов мне использовать для этого?

Ответы [ 3 ]

2 голосов
/ 22 июня 2009

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

Я хочу добавить одну точку - даже если вы пойдете по пути абстрактного класса, я все равно рекомендую создать интерфейс. Вы никогда не знаете, когда вы захотите иметь подкласс, который действует как другие, но по какой-то причине ему действительно нужно наследовать другой класс. Абстрактные базовые классы отлично подходят для сохранения кода реализации. Тем не менее, интерфейсы более гибкие, поэтому, если нет веских причин (т. Е. Ваши тесты показывают, что вы не можете снизить производительность вызовов виртуальных методов), используйте интерфейс, а также абстрактный базовый класс, где это имеет смысл.

Мое общее правило по этому поводу: используйте интерфейсы для определения API и используйте абстрактные базовые классы, чтобы позволить реализациям интерфейса совместно использовать код.

2 голосов
/ 22 июня 2009

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

Так что только с интерфейсами вы получите следующее.

class Transformation : INode, ITransformation { }
class GraphicsObject : INode, IGraphicsObject { }

Полагаю, вы можете выделить общий код для конкретного узла в базовый класс.

abstarct class Node : INode { }

class Transformation : Node, ITransformation { }
class GraphicsObject : Node, IGraphicsObject { }
1 голос
/ 22 июня 2009

Разница будет в том, если между всеми классами, которые вы можете поместить в абстрактный класс, существует общий код и если им всем нужен один и тот же набор методов с этим кодом. Если это так, переходите к абстрактному классу. Если нет общего кода или вы в конечном итоге сделаете общий код, который не должен быть общим, то используйте интерфейс.

...