【问题标题】:How to avoid "incomplete implementation" warning in partial base class如何避免部分基类中的“不完整实现”警告
【发布时间】:2010-05-18 04:13:12
【问题描述】:

我创建了一个我的类需要实现的协议,然后将一些常用功能分解到一个基类中,所以我这样做了:

@protocol MyProtocol
- (void) foo;
- (void) bar;
@end

@interface Base <MyProtocol>
@end

@interface Derived_1 : Base
@end

@interface Derived_2 : Base
@end

@implementation Base
- (void) foo{
//something foo
}
@end

@implementation Derived_1
- (void) bar{
//something bar 1
}
@end

@implementation Derived_2
- (void) bar{
//something bar 2
}
@end

这样,在我的代码中,我使用了一个通用的 id

代码有效(只要不直接使用 Base),但编译器在 Base 实现结束时会出现警告:

Base类实现不完整

有没有办法避免这个警告,或者更好的方法来获得 Objc 中这种部分实现的抽象基类行为?

【问题讨论】:

    标签: objective-c oop coding-style


    【解决方案1】:

    你可以想象这样的事情:

    @implementation Base
    
    - (void)bar
    {
        if ([self class] == [Base class]) {
            [self doesNotRecognizeSelector:_cmd];
        }
    }
    
    @end
    

    这样,您就有了一个实现,但默认情况下它会引发异常。但是,如果派生类意外调用[super bar] 或没有覆盖bar,则不会引发异常。如果这不是您想要的,您可以将其缩短为:

    @implementation Base
    
    - (void)bar
    {
        [self doesNotRecognizeSelector:_cmd];
    }
    
    @end
    

    在这种情况下,即使子类调用[super bar] 或不覆盖bar,也会引发异常。

    【讨论】:

    • 好的,这至少会强制在大多数派生类中实现。不过,对未实现的方法有一个编译时警告会很好,但我想没有办法(?)在 Obj-c 中做这个基类部分实现的正确方法吗?
    • 并非如此。正如其他人所指出的,Objective-C 没有抽象基类。我曾经用来模仿他们的每一种方法都只会让你走上正轨。
    【解决方案2】:

    在您的协议定义中,您需要在 @optional 关键字下声明您的方法。

    您的代码应如下所示:

    @protocol MyProtocol
    
    @optional
    - (void) foo;
    - (void) bar;
    
    @end
    

    在 SO 上看到这个question

    【讨论】:

    • 不会@optional 使方法实现在派生类中也是可选的吗?我希望强制最派生类实现基类中未实现的方法(在本例中为“bar”)。
    • @garph0, 你不能在 Obj-C 中挑选。
    【解决方案3】:

    在 Obj-C 中,没有抽象类的概念。所以,你不能让你的基类是抽象的(这意味着不要'实现协议中的所有方法)。您只能有 2 个选择。让protocol中的方法为optionol,然后在派生类中自己实现。或者,强制层次结构中的所有类实现它,但让调用者注意不要调用不正确的方法

    【讨论】:

      【解决方案4】:

      我做这样的事情

      @protocol MyProtocol
      - (void) foo;
      - (void) bar;
      @end
      
      @interface BaseAbstract
      - (void) bar; // give a default implementation
      @end
      
      @interface Derived_1 : BaseAbstract<MyProtocol>
      // you will get a compiler warning for foo() since it is not implemented
      
      // you will NOT get compiler for bar() warning since a default 
      // implementation is inherited
      @end
      
      @interface Derived_2 : BaseAbstract<MyProtocol>
      @end
      
      typedef BaseAbstract<MyProtocol> Base;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-04
        • 2016-12-25
        • 2021-02-04
        • 2021-04-29
        • 1970-01-01
        相关资源
        最近更新 更多