Ответ 1
Хороший способ приблизиться к этой проблеме - сначала подумать об этом в общей теории программирования, а затем в более конкретном контексте Objective-C.
Абстрактный класс - это класс, предназначенный исключительно для подкласса, его не нужно создавать. Абстрактный класс объявляет что-то и имеет также реализацию для этого.
В чем причина такого специального класса? Он моделируется после реальной жизни!:) Представьте себе абстракцию - животное. Что общего с каждым животным? Они все живые (и могут умереть). Им нужно есть. Может перемещаться в пространстве. Эти черты являются общими и фундаментальными для всех животных. Я не слышал о животном, который не нуждается в еде, не может двигаться и жить вечно. Другое дело, что существует много не столь фундаментальных различий между различными животными.
На планете нет животного, которое чисто абстрактное животное. Этот набор фундаментальных поведений, черт просто недостаточно, чтобы быть конкретным животным.. Существует подразумеваемый принцип, который должен быть конкретным животным, у вас должны быть некоторые дополнительные черты помимо тех фундаментальных.
Теперь, в программировании, нам нужно как-то
- выразить эти основы (объявление )
- имеют способ описать, как они работают (реализация)
- привязать их к классу
- предотвратить создание экземпляра
- убедитесь, что любое конкретное животное будет иметь их (наследование)
Мы знаем, каковы эти основы (объявленный публичный интерфейс), и мы на практике знаем, как они проявляются конкретно (реализация этих объявленных черт). Мы хотим, чтобы они были унаследованы всеми конкретными сущностями. Поэтому мы делаем это в абстрактном классе, потому что он удовлетворяет указанным выше условиям. Он содержит все основы, имеет их реализацию, но не может быть создан сам по себе.
Абстрактный класс представляет собой абстракцию над множеством связанных объектов, которые фиксируют то, что в корне распространено между всеми из них., рассказывает нам, как это делается... и гарантирует, что все более конкретные объекты наследуют это.
Интерфейс - это нечто меньшее. Пусть у есть реальная аналогия. Человек, робот, животное, ветер (сила природы). Некоторые люди могут петь. У робота встроен модуль синтезатора голоса, поэтому он может петь. Осенний ветер, касающийся моего стекла, "поет", я могу вам сказать. И Тинка (r.i.p) моя собака, на самом деле была хорошей певицей.
Но на самом деле, "пение" между этими четырьмя имеет единственное общее - вы можете слышать это как приятный звук в ушах. Как пение происходит для этих четырех, в действительности отличается много. (Реализация)
Еще одно осложнение - это, конечно, не все люди, собаки, ветры или животные могут петь. Некоторые из них могут.
Итак, как мы могли бы отразить эту ситуацию в программировании? Через интерфейс:)
У вас может быть интерфейс под названием "SingInterface"
, который в нашем случае имеет одно объявленное поведение/признак/функциональность и sing
. Интерфейс просто объявляет что-то и что он. Интерфейс не говорит, как это делается, нет конкретной реализации. Он также не говорит, кто может это сделать, черта в интерфейсе не ограничивается одним типом или одним классом. (см. http://www.nasa.gov/centers/goddard/universe/black_hole_sound.html)
Интерфейс представляет собой список от 1 до N признаков/функциональных возможностей, не зная, как конкретно они будут реализованы, и этот список признаков/функциональных возможностей, которые могут быть произвольными (для них не существует правил), относящихся к объектам из разрозненных множеств, которые в корне разные (животные или роботы).
Объектно-ориентированное программирование заимствует многие концепции из реальной жизни. Вот почему эти аналоги работают так хорошо.
В Objective C, вопреки некоторым другим языкам (С# и т.д.),
нет поддержки уровня языка для абстрактных классов. невозможно гарантировать, что класс является абстрактным во время компиляции. Класс является абстрактным только по соглашению и соблюдает это соглашение разработчиками.
Что касается интерфейсов, в объекте C используется слово "протокол". Это просто другое слово для одного и того же.
В объективе C вы можете
-
код для интерфейса..с объявлением какого-либо объекта как
id<protocolName>
-
добавить дополнительные функции классам, объявив, что они соответствуют протоколу, который вы выполняете в интерфейсе класса
@interface ClassName <protocolName>
Таким образом, может быть даже случай, когда ваш класс является подклассом абстрактного класса, а также соответствует некоторому протоколу.