Чем абстрактный класс отличается от Интерфейса от точки проектирования? - PullRequest
0 голосов
/ 12 апреля 2010

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

Ответы [ 7 ]

4 голосов
/ 12 апреля 2010

Абстрактный класс может (и обычно делает) предоставлять некоторую реализацию.

И интерфейс не может обеспечить какую-либо реализацию.

2 голосов
/ 12 апреля 2010

Основные отличия от проектной точки зрения заключаются в том, что:

  • Вы можете объявить контракт на конструктор реализующих классов, создав защищенный конструктор в базовом абстрактном классе.
  • вы можете предоставить реализации методов, используемых базовыми классами
  • вы можете заключить контракт в контракт (например, проверить аргументы метода)
  • Вы можете предоставить «схему вызова» при создании неабстрактных методов, которые вызывают абстрактные методы типа, реализуемого производными классами. Это может быть полезно для реализации абстракции алгоритма в производных классах, в то время как базовый класс реализует всю логику обработки - подготавливает и проверяет данные и позволяет реализовать фактический алгоритм обработки производными классами.

Так что я бы сказал, что вы правы в утверждении, что «абстрактный класс абстрагирует реализацию поведения, в то время как интерфейс абстрагирует тип, который реализует поведение»

Абстрактный класс: предоставляет требование для реализации некоторых методов (вы переопределяете методы абстрактного класса )

Интерфейс: определяет только контракт. Указывает, что класс, реализующий интерфейс, имеет методы интерфейса (вы реализует интерфейс )

Например:

  • реализуя интерфейс в существующем классе, вы просто объявляете о добавлении методов интерфейса в контракт класса. Класс может уже реализовывать все методы интерфейса, и вам не нужно ничего менять в существующем классе.

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

0 голосов
/ 12 апреля 2010

Оба имеют специфическое использование в соответствии с языком design-abstract. Класс разработан как базовый класс и не может быть создан. Когда вам нужно определить только контракт (без реализации), которому каждый класс-исполнитель должен следовать по-своему, тогда вы должны использовать интерфейсы. Также -

Может быть базовым классом для наследования

абстрактный класс - да Интерфейс - нет

Может иметь реализацию

абстрактный класс - Да Интерфейс -Нет

0 голосов
/ 12 апреля 2010

Чисто с точки зрения дизайна, и будучи независимым от языка, интерфейс - это контракт между вашим классом и клиентом, обещающий, что он делает, а не как он это делает. Это использование подразумевается в мантре «программа к интерфейсу».

Поскольку языки, такие как C ++, не имеют интерфейсов, абстрактный класс является единственным способом его представления. Для языков, в которых интерфейс является конструкцией первого класса, приемлем любой из этих способов, и в выборе есть компромиссы. Конечно, есть и другие технические различия в реализации между языками, но я не думаю, что вы спрашивали об этом.

Есть интервью с Эрихом Гаммой , в котором он обсуждает некоторые различия.

Чтобы ответить на ваш вопрос, я думаю, что это имеет смысл с теоретической точки зрения. С практической точки зрения, это, вероятно, зависит от того, на каком языке вы программируете:)

0 голосов
/ 12 апреля 2010

Интерфейс = чистый абстрактный класс (абстрактный класс без реализации)

0 голосов
/ 12 апреля 2010

Обычно абстрактный класс реализует некоторое поведение, но оставляет какое-то специализированное поведение нереализованным.

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

class MyServer(Networkserver):
    // process() is called whenever a client has sent a request
    function process(data):
        ...

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

0 голосов
/ 12 апреля 2010

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

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