Как узнать, когда безопасно использовать родительский метод в подклассах NS? - PullRequest
0 голосов
/ 02 сентября 2010

Например, когда я использую NSMutableDictionary, я знаю, что он наследует все методы NSDictionary, но как я могу знать / доверять, что он переопределил поведение этих методов, если я хочу использовать методы NSDictionary (например, как +dictionaryWithObjectsAndKeys) чтобы создать мой изменяемый экземпляр словаря?

В целом, отвечает ли Framework за то, чтобы подклассы не наследовали вслепую методы, которые могут потенциально сломать экземпляры подкласса, если они используются? Или кодер обязан знать, не использовать их? Если Square наследуется от Rectangle, и через наследование я могу позвонить

Square *newSquare = [[Square alloc] init];
[newSquare setWidth:3 andHeight:6]; //instead of -(void)setSide:(int)side

Я "сломал" квадрат и другие методы, которые зависят от ширины, равной высоте, теперь не будут работать. Каковы правила игры?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2010

Я бы не стал доверять родительскому методу удобства для вызова вашего наследуемого метода init. Например, этот словарный метод может быть определен как:

+ (id)dictionaryWithObjectsAndKeys:...
{
    return [[[NSDictionary alloc] initWithObjectsAndKeys:...] autorelease];
}

Если этот метод определен таким образом, он даже не узнает о вашей реализации.

Вы должны создать свой собственный удобный метод. Нечто подобное будет в вашей реализации MyDictionary:

+ (id)myDictionaryWithObjectsAndKeys:...
{
    return [[[MyDictionary alloc] initWithObjectsAndKeys:...] autorelease];
}

-

Кроме того ... * * 1013

Вы, вероятно, должны наследовать Rectangle от Square. Наследование является аддитивным. Вы можете описать Square одним размером (шириной), но для Rectangle у вас есть два размера (ширина, высота).

0 голосов
/ 02 сентября 2010

Правило будет только выставлять то, что вы позволите переопределить, это означает, помещать в ваш интерфейс то, что действительно общедоступно.При необходимости прямо указывайте, что при переопределении определенного вызова метода в какой-то момент [super methodName].

В вашем примере вы переопределите метод - (void)setWidth:(int)width andHeight:(int)height, и вы бы хотели выдать ошибку, если width != height.Или вы можете также выдать ошибку и заставить пользователя использовать только - (void)setSide:(int)side.

Например, вы можете сделать:

// If you want to test and accept cases when width == height
- (void)setWidth:(int)width andHeight:(int)height {
    NSAssert(width == height, NSLocalizedString(@"This is a Square. Width has to be height.", nil));

    [super setWidth:width andHeight:height];

    // Or

    [self setSide:width];
}

// Or if you want to completely prohibit the usage of the method
- (void)setWidth:(int)width andHeight:(int)height {
    NSAssert(NO, NSLocalizedString(@"This is a Square! Please use - (void)setSide:(int)side method.", nil));
}

Если вы хотите выдать некоторые ошибки и предупреждения навремя компиляции, вы можете использовать в объявлении ваших методов некоторые макросы, определенные в NSObjCRuntime.h.

...