ObjC: я должен указать наследование в заголовочном файле? - PullRequest
1 голос
/ 01 сентября 2011

Типичные примеры для объекта ObjC такие (для файла заголовка):

@interface A: B {
    int x;
    int y;
}
@end

Можно ли избежать спецификации наследования (т. Е. B здесь) в заголовочном файле?


В моем случае каркас A определяет этот класс A, а другой (под) каркас B определяет класс B (который является подклассом NSView). Ссылки на B. В моем приложении я ссылаюсь на A, и мне не нужно ничего знать о B, за исключением того, что это подкласс NSView. И я хочу избежать ссылки на B. Но если в заголовочном файле есть B, я думаю, что не могу избежать этого, поэтому я спрашивал, как этого избежать.

Ответы [ 7 ]

1 голос
/ 01 сентября 2011

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

1 голос
/ 01 сентября 2011

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

0 голосов
/ 01 сентября 2011

нет.

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

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

Обновление - демонстрация частных реализаций

Частные реализации могут быть полностью непрозрачными.Если вы их выставите, вот два способа реализовать частные реализации, которые видны клиентам:

через протокол:

// MONDrawProtocol.h
// zero linkage required
// needs to be visible to adopt
// may be forwarded
@protocol MONDrawProtocol
- (void)drawView:(NSView *)view inRect:(NSRect)rect;
@end

// MONView.h
@protocol MONDrawProtocol;

@interface MONView : NSView
{
    NSObject<MONDrawProtocol>* drawer;
}

@end

// MONView.m

#include "MONDrawProtocol.h"

@implementation MONView

- (void)drawRect:(NSRect)rect
{
    [self.drawer drawView:self inRect:rect];
}

@end

через базу:

// MONDrawer.h
// base needs to be visible to subclass and types which use MONDrawer
// may be forwarded
@interface MONDrawer : NSObject
- (void)drawView:(NSView *)view inRect:(NSRect)rect;
@end

// MONView.h
@class MONDrawer;
@interface MONView : NSView
{
    MONDrawer * drawer;
}

@end

// MONView.m

#include "MONDrawer.h"

@implementation MONView

- (void)drawRect:(NSRect)rect
{
    [self.drawer drawView:self inRect:rect];
}

@end
0 голосов
/ 01 сентября 2011

У меня есть одно решение сейчас.Вместо того, чтобы предоставлять класс, я просто предоставляю такую ​​функцию:

NSView* allocA();

Внутри структуры A, A является подклассом B.

0 голосов
/ 01 сентября 2011

не могли бы вы просто включить фиктивную версию класса, который вы унаследовали, из самого заголовка A? Не уверен, что это вызовет проблемы, но это позволит вам немного очистить ваши требования к ссылкам. B-new тогда может быть категорией B'Original

0 голосов
/ 01 сентября 2011

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

0 голосов
/ 01 сентября 2011

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

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