Абстрактные классы против интерфейсов для представления семьи - PullRequest
3 голосов
/ 25 апреля 2009

Абстрактные классы описаны как полезные для семейства объектов (например, могут использоваться для животных, которые являются млекопитающими). Однако, какая разница между использованием интерфейса или абстрактного класса для представления семейства связанных объектов?

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

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

Это правильный путь? Имеет ли какое-либо значение выбор одной конструкции (абстрактной или интерфейсной) для представления семейства?

Ответы [ 3 ]

3 голосов
/ 25 апреля 2009

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

Вот пример.

Немецкая овчарка, Золотистый ретривер, Бигль

Все эти три объекта являются собаками, и поэтому они имеют определенное общее состояние (плотоядное животное, 4 ноги и т. Д.), А также они имеют определенное переопределенное поведение (кора, штаны и т. Д.). В этом случае было бы разумнее создать абстрактный класс Dog для хранения этого общего состояния и поведения и создать подтипы Dog для каждого типа собак.

Карандаш, ручка, мел

Эти объекты не имеют общего состояния и не могут иметь общее поведение. Тем не менее, вы можете заметить, что у них есть что-то общее - они являются пишущими . Эти объекты лучше всего построить отдельно и без базового класса, а затем связать их вместе с интерфейсом Writable, который предоставляет метод Write каждого типа.

0 голосов
/ 25 апреля 2009

С помощью абстрактных классов вы можете обеспечить реализацию, которая необходима и используется всеми классами в вашей иерархии. Поэтому вы повторно используете код. Вы можете разрешить производным классам переопределять поведение по умолчанию или нет, но, по крайней мере, вы предоставляете базовые функции, такие как дыхание для новорожденного животного. Однако с интерфейсами вы не можете предоставить какую-либо реализацию. Вы просто определяете контракт, для которого все классы, которые наследуют этот интерфейс, должны соблюдать и обеспечивать реализацию. Это может привести к повторяющемуся и повторяющемуся коду в иерархии классов.

Интерфейсы не очень хороши для расширяемости, и вам нужно беспокоиться о версии. Вы решаете внести изменения в существующий интерфейс, но вскоре вы поймете, что существует множество классов, которые вам может потребоваться изменить. Подумайте о добавлении метода Breath в интерфейс IMammal, который уже используется многими млекопитающими. Вам нужно будет пойти и предоставить реализацию Breath для каждого. С помощью абстрактного класса вы можете просто добавить метод Breath и предоставить базовую реализацию, не беспокоясь о существующих производных классах. Таким образом, абстрактные классы более гибки с точки зрения развития вашей иерархии и API.

0 голосов
/ 25 апреля 2009

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

Как всегда, основным принципом проектирования, когда дело доходит до разработки, является

Дизайн к интерфейсу, а не реализации

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