Какие факторы следует учитывать при выборе между интерфейсами и абстрактными классами? - PullRequest
1 голос
/ 25 января 2010

При разработке своего программного обеспечения я начал с интерфейсов, так как это кажется «стандартом». Затем я переключился на абстрактные классы, потому что они кажутся лучше подходящими для рассматриваемой проблемы. Однако я не уверен, что упустил некоторые соображения при выборе дизайна. Кроме вопросов, специфичных для предметной области, о которых я подумал, какие факторы следует учитывать при выборе между интерфейсами и классами тезисов?

Ответы [ 5 ]

2 голосов
/ 25 января 2010

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

Отрицательно делать и то и другое: больше липучки.

пример псевдокода:

interface IVehicle
{
    void PutCarInGear(Int speed);
}

abstract class Vehicle : IVehicle
{
    public void PutCarInGear(Int speed)
    {
        //base implementation
    }
}

Обратите внимание, что в этом примере кто-то может создать свой собственный класс, который реализует IVehicle, а затем передать его любому объекту, который принимает IVehicle. Этот объект НЕ ДОЛЖЕН быть потомком абстрактного класса Vehicle. Следовательно, если вы ожидаете, что в методе PutCarInGear() произойдет что-то конкретное, вполне вероятно, что новый класс НЕ будет соответствовать этому ожиданию. Однако до тех пор, пока не имеет значения, что делают реализации IVehicle, это самая гибкая абстракция, имеющая как абстрактный базовый класс, так и интерфейс.

2 голосов
/ 25 января 2010

Наследование определяет сходство состава. Интерфейсы определяют сходство поведения. Оттуда вы должны решить, достаточно ли важна композиция для переопределения поведения.

0 голосов
/ 19 сентября 2016

Сохраните его как абстрактный класс, если он является отношением «является» и должен выполнять подмножество / все функции.Сохраните его как интерфейс, если это отношение «следует делать».

0 голосов
/ 25 января 2010

Используйте абстрактный класс, если у вас есть несколько экземпляров, которые изменяют шаблон Template Method.

Скажем, у вас есть три парсера. Один разграничивает данные файла на «,», другой на «», а другой на «|»

Затем вы можете иметь CommaParser, SpaceParser и PipeParser, все они подклассируют абстрактный парсер и переопределяют абстрактный метод, getDelimiter()

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

0 голосов
/ 25 января 2010

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

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