Это хороший стиль, чтобы объявить методы в .h, когда они должны быть перезаписаны подклассом? - PullRequest
1 голос
/ 02 ноября 2009

У меня есть класс, который должен быть абстрактным. Это означает: когда кто-то подклассирует его, несколько методов ДОЛЖНЫ быть перезаписаны.

Но с другой стороны, эти методы не предназначены для вызова вручную из любого места, кроме как внутри абстрактного класса (суперкласса подкласса).

Должен ли я в любом случае объявлять эти методы в .h или я могу просто добавить в .h комментарии, в которых говорится "вы должны перезаписать -foo и -bar"? Или есть лучший шаблон для создания абстрактных методов?

Ответы [ 4 ]

5 голосов
/ 02 ноября 2009

Похожие: Есть ли способ создать абстрактный класс в Objective C?

Objective-C фактически не имеет способа объявить класс абстрактным. От Документы Apple :

Абстрактные классы

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

В отличие от некоторых других языков, Objective-C не имеет синтаксиса для помечать классы как абстрактные помешать вам создать экземпляр абстрактного класса.

Класс NSObject является каноническим Пример абстрактного класса в Какао. Вы никогда не используете экземпляры Класс NSObject в приложении - это не было бы хорошо ни для чего; Это будет общий объект с способность ничего не делать в частности.

Класс NSView, с другой стороны, предоставляет пример абстрактного экземпляры классов, которые вы могли бы иногда использовать напрямую.

Абстрактные классы часто содержат код это помогает определить структуру приложение. Когда вы создаете подклассы этих классов, экземпляры из ваших новых классов подходят без особых усилий в структуру приложения и автоматически работать с другими объектами.

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

Вы также можете использовать протокол , чтобы заставить классы реализовывать определенные методы.

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

3 голосов
/ 02 ноября 2009

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

2 голосов
/ 02 ноября 2009

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

@interface MyBaseClass : NSObject {
}
- (void)foo;
@end

@interface MyBaseClass(ProtectedMethods)
- (void)bar;
@end

@interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
@end

Вы можете поместить все в один заголовок, или вы можете поместить свои защищенные и абстрактные объявления в отдельный "защищенный" заголовок, скажем MyClassProtected.h, предназначенный для включения только вашими реализациями подкласса. Это зависит от того, насколько сильно вы хотите «спрятать» ваши защищенные методы.

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

1 голос
/ 02 ноября 2009

Как говорили другие, Objective-C не поддерживает чисто виртуальные классы.

Вы можете использовать чисто виртуальное поведение во время выполнения. Самый простой способ сделать это - использовать _cmd среды выполнения Objective C и -doesNotRecognizeSelector:

NSObject.
- (void)iMustBeImplementedInaSubclass;
{
    [self doesNotRecognizeSelector:_cmd];   // Pure virtual
}

Как говорит Бен, вам, вероятно, лучше использовать протокол для правильной разработки API.

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