如何知道何时可以安全地在 NS 子类中使用父方法?

发布于 2024-09-17 20:17:39 字数 474 浏览 2 评论 0原文

举个例子,当我使用 NSMutableDictionary 时,我知道它继承了 NSDictionary 的所有方法,但是如果我想使用 NSDictionary 方法(例如 +dictionaryWithObjectsAndKeys) 来创建我的可变字典实例?

更一般地说,框架是否有责任确保子类不会盲目继承可能会破坏子类实例(如果使用)的方法?或者编码员有责任知道不使用它们?如果 Square 继承自 Rectangle,并且通过继承,我可以称

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

我已经“破坏”了正方形,并且其他依赖于宽度等于高度的方法现在将不起作用。游戏规则是什么?

As an example, when I'm using an NSMutableDictionary, I know it inherits all the methods of NSDictionary, but how can I know/trust that it has overridden the behavior of those methods if I want to use NSDictionary methods (such as +dictionaryWithObjectsAndKeys) to create my mutable dictionary instance?

More generally, is it the Framework's responsibility to make sure subclasses don't blindly inherit methods that can potentially break instances of the subclass if used? Or is it the coder's responsibility to know not to use them? If Square inherits from Rectangle, and via inheritance I can call

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

I've "broken" the square and other methods which depend on width being equal to height will not work now. What are the rules of the game?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

债姬 2024-09-24 20:17:39

该规则将仅公开您允许覆盖的内容,这意味着将真正公开的内容放在您的界面上。必要时明确声明在某个时刻重写特定方法时调用 [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 上定义的一些宏。

The rule would be only expose what you would allow to be override it means, put on your interface what is really public. When necessary explicitly state that when overriding an specific method call at some point [super methodName].

On your example you would override the method - (void)setWidth:(int)width andHeight:(int)height, and you would like to throw an error if width != height. Or you could also throw an error and force the user to only use - (void)setSide:(int)side.

For example you could do:

// 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));
}

If you would like to throw some errors and warnings at compilation time, you could use on the declaration of your methods, some of the macros defined on NSObjCRuntime.h.

李不 2024-09-24 20:17:39

我不相信父方便方法会调用您的继承 init 方法。例如,该字典方法可以定义为:

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

如果该方法是这样定义的,那么它甚至不会知道您的实现。

您必须创建自己的便捷方法。您的 MyDictionary 实现中会出现类似的情况:

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

--

另外...

您可能应该从 Square 继承 Rectangle 。继承是累加性的。您可以用一种尺寸(宽度)来描述正方形,但对于矩形,您可以有两种尺寸(宽度、高度)。

I wouldn't trust the parent convenience method to call your inheriting init method. For example, that dictionary method could be defined as:

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

If that method is defined that way then it won't be even be aware of your implementation.

You'd have to create your own convenience method. Something like would be in your MyDictionary implementation:

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

--

Also...

You probably should inherit Rectangle from Square. Inheritance is additive. You can describe Square with one size (width), but for Rectangle you have two sizes (width, height).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文