2014-09-17 4 views
1

Хорошо, есть несколько вопросов с «Протоколом» и «Наследование», но я не могу найти ответ на свой вопрос. У меня есть класс с протоколом. Например:Целевые C-протоколы и наследование

@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 можно ли наследовать один класс и принять протокол из другого класса? Я предполагаю, что я пытаюсь понять, возможно ли, что два объекта могут общаться друг с другом через делегатов, не наследуя от класса этого протокола (я надеюсь, что у меня есть смысл).

Заранее благодарен!

ответ

0

На практике ваш код будет очень странным.

Во-первых, у вас нет класса с протоколом. У вас есть протокол с именем SomeDelegate. Тогда у вас есть класс SomeClass, который не связан с протоколом. Ну, у него есть переменная экземпляра, которая поддерживает SomeDelegate, но это не имеет ничего общего с протоколом.

Затем вы создаете класс, который является подклассом SomeClass, и поддерживает протокол SomeDelegate. Это необычно. Я имею в виду, что DiffClass поддерживает сам протокол, и имеет делегата, поддерживающего протокол. Это немного странно.

Тем не менее, DiffClass является подклассом SomeClass, и вы пообещали, что он поддерживает протокол SomeDelegate, так что все в порядке.

Но на самом деле: протокол не относится к классу. Я не знаю, что заставило вас думать об этом, но вы должны немедленно удалить это из своего мозга. Протокол совершенно другой и полностью независим от класса. Это набор требований, которые любой класс может выполнять или не выполнять. Он существует независимо от любого класса. Поскольку протокол представляет собой набор требований, класс может поддерживать этот протокол, заявляя, что он делает (добавление), и добавляя необходимые методы.

+0

Это очень краткий и очень понятный. Именно ответ я искал. Я запутался, связав протокол с концепцией интерфейса на других языках, поэтому я задавался вопросом, как они используются для создания механизмов делегирования в Objective-C. Теперь я понимаю. Спасибо! –

0

Чтобы ответить на ваш первый вопрос, 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 для двухсторонней связи.

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

+0

Очень ясный ответ! Тот факт, что многие учебники объявляли протоколы в том же заголовочном файле, что и классы, было другой вещью, которая немного смутила меня. Прекрасно, что объект может наследовать один класс и соответствовать протоколам, которые не обязательно связаны с родительским классом для связи с другими объектами! Мне также очень нравится идея, что вы рассказывали об использовании протоколов для двусторонней связи! Спасибо! –

0

Ответ на вопрос 1: с утверждением

@interface DiffClass: SomeClass<SomeDelegate> 

В DiffClass унаследован от SomeClass, а также соответствует протоколу (интерфейс) SomeDelegate.

Ответ на вопрос 2: В Objc вы можете наследовать только один родительский класс (множественное наследование не поддерживается), но вы можете согласовать столько, сколько требуется для протоколов (интерфейсов).

Позволяет взять пример приложения. Shape является родительским классом, а RectangleShape, LineSahpe, TextShape, CircleShape - дети из класса 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 

Вы можете иметь метод для протокола, как это, чтобы переместить все Shaped, которые в соответствии Movable протокол (интерфейс).

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

} 

Вы можете реализовать связь вместо перемещения фигур. Протоколы действительно полезны во время расширенного программирования.

Надеюсь, это поможет вам ... пожалуйста, обратная связь.

+0

Очень ясно! Спасибо! Я был смущен всей концепцией протокола. Я не знал класс, а протокол - отдельные объекты. Я думаю, что путаница происходит из-за того, что я связывал протокол как интерфейс на других языках ООП, а классы «расширяют» эти интерфейсы и реализуют их методы. Теперь, когда я понимаю протоколы, я вижу, насколько они полезны и эффективны. –

Смежные вопросы