【问题标题】:Objective C Protocols and InheritanceObjective C 协议和继承
【发布时间】:2014-09-17 14:05:27
【问题描述】:

好的,“协议”和“继承”有几个问题,但我真的找不到我的问题的答案。我有一个带有协议的课程。例如:

@class SomeClass;

@protocol SomeDelegate <NSObject>

@optional
     -(void) someMethod;

@end

@interface SomeClass : NSObject
{
     id<SomeDelegate> delegate;
}

@property id<SomeDelegate> delegate;

-(void) thisDoesStuff;

@end

然后我有一个不同的类,其对象将是 SomeClass 对象的委托:

@interface DiffClass: SomeClass<SomeDelegate>

// This method will conform to the one specified on the protocol
-(void) someMethod;

@end

我的问题是,DiffClass 是否继承自 SomeClass?我正在考虑使用 Objective C 中的语法进行继承:

@interface ClassA : SuperClassOfClassA

在上面,ClassA 继承自 SuperClassOfClassA。

此外,在 Objective C 中,是否可以从一个类继承并采用不同类的协议?我想我想知道的是,两个对象是否有可能通过委托相互通信,而不必从该协议的类继承(我希望我说得通)。

提前致谢!

【问题讨论】:

    标签: objective-c inheritance protocols


    【解决方案1】:

    实际上,您的代码会很奇怪。

    首先,您没有带有协议的类。您有一个名为 SomeDelegate 的协议。然后你有一个类 SomeClass,它与协议无关。好吧,它有一个支持 SomeDelegate 的实例变量,但这与协议无关。

    然后你创建一个类,它既是 SomeClass 的子类,并且支持 SomeDelegate 协议。这很不寻常。我的意思是 DiffClass 都支持协议本身, 有一个支持协议的委托。这有点奇怪。

    尽管如此,DiffClass 是 SomeClass 的子类,并且您承诺它支持 SomeDelegate 协议,所以没关系。

    但实际上:协议不属于一个类。我不知道是什么让你这么想,但你必须立即把它从你的大脑中删除。协议是完全不同的东西,完全独立于类。这是任何课程可能满足也可能不满足的一组要求。它独立于任何类而存在。因为一个协议是一组需求,一个类可以通过声明它支持该协议(添加)并添加所需的方法。

    【讨论】:

    • 这很简短,也很清楚。正是我正在寻找的答案。我对将协议与其他语言中的接口概念相关联感到困惑,这就是为什么我想知道它们如何用于在 Objective-C 中制作委托机制。不过我现在明白了。谢谢!
    【解决方案2】:

    要回答您的第一个问题,DiffClass 确实继承自您编写的 SomeClass。但它不需要从 SomeClass 继承。下面我会说得更透彻一些。

    协议是类采用的方法(和属性)的声明。它不必与类相关,尽管它通常与委托模式相关。

    例如,您可以有一个仅声明协议的标头。我们将文件命名为 NewProtocol.h

    @protocol NewProtocol<NSObject>
    @optional
    - (void)newMethod;
    @end
    

    那么任何类都可以采用该协议。对于上面的示例,这可能是 DiffClass。您无需在类接口中再次声明来自 NewProtocol 的方法。

    // You would need to import NewProtocol.h
    // Note that this does NOT inherit from SomeClass.
    @interface DiffClass : NSObject<NewProtocol>
    @end
    

    那么 DiffClass 的实现就需要提供声明的协议方法。

    @implementation DiffClass
    
    - (void)newMethod {
      // Do stuff.
    }
    
    @end
    

    那么 SomeClass 就可以拥有上面声明的协议的属性。

    @interface SomeClass : NSObject
    
    // Often you will want weak for delegates as they can cause retain cycles otherwise.
    @property(nonatomic, weak) id<NewProtocol> thingThatImplementsNewProtocol;
    
    -(void) thisDoesStuff;
    
    @end
    

    DiffClass 现在不从 SomeClass 继承,但可用于与 SomeClass 通信。您可以声明 SomeClass 采用的第二个协议和 DiffClass 上的属性以进行双向通信。

    为了简单起见,协议通常在与类相同的头文件中声明,因为它们旨在作为特定对象的委托。

    【讨论】:

    • 非常明确的答案!许多教程在与类相同的头文件中声明协议这一事实让我有点困惑。一个对象可以从一个类继承并遵守不一定与父类关联的协议以与其他对象通信,这真是太棒了!我也非常喜欢您提出的关于使用双向通信协议的想法!谢谢!
    【解决方案3】:

    回答问题1:用语句

    @interface DiffClass: SomeClass<SomeDelegate>
    

    DiffClass 继承自 SomeClass 并且还符合协议(接口)SomeDelegate

    对问题 2 的回答:在 Objc 中,您只能从一个父类继承(不支持多重继承),但您可以遵循任意数量的协议(接口)。

    让我们以绘图应用为例。 Shape 是父类,RectangleShapeLineSahpeTextShapeCircleShape 是 Shape 类的子类。所有四个孩子都从其父 Shape 继承。但是您需要移动除 LineShape 之外的形状。在那里,您可以将协议(接口)设置为Movable。你可以这样做。

    @protocol Movable <NSObject>
    
    @end
    
    
    @interface Shape : NSObject
    
    @end
    
    
    @interface RectangleShape : Shape <Movable>
    
    @end
    
    
    @interface LineSahpe : Shape // cannot be moved, just for an example.
    
    @end
    
    
    @interface TextShape : Shape <Movable>
    
    @end
    
    
    @interface CircleShape : Shape <Movable>
    
    @end
    

    您可以使用这样的协议方法来移动所有符合 Movable 协议(接口)的 Shaped。

    - (void)move:(id <Movable>)movableShape {
    
    }
    

    您可以实现通信而不是移动形状。协议在高级编程中非常有用。

    希望对您有所帮助...请反馈给我。

    【讨论】:

    • 非常清楚!谢谢!我对协议的整个概念感到困惑。我不知道类和协议是独立的实体。我认为混淆来自这样一个事实,即我将协议与其他 OOP 语言中的接口相关联,并且类“扩展”了这些接口并实现了它们的方法。现在我了解了协议,我可以看到它们是多么有用和强大。
    猜你喜欢
    • 2011-07-31
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多