协议和访问另一个类的方法

时间:2012-05-29 17:53:22

标签: iphone objective-c ipad class protocols

所以我对objective-c相当新,并试图绕过协议。我将用一个例子来说明我的问题。

假设我有一个执行各种方法的“Calculate”类。我还有“Class1”和“Class2”,它们在“计算”中执行相同的方法。

根据我的理解,我可以使用协议从“计算”访问方法而无需继承(因此无需在Class1和Class2中复制相同的代码)。

我的理解是我必须在Class1和Class2中实现协议,因此我必须输入那些方法。那么协议的重点是什么?

我想使用“计算”​​的方法而不使它成为Class1和Class2的超类。所以我开始探索协议,我已经阅读了文档,但我仍然不明白这是如何实现的。如果有人可以解释外行人的协议,我们将不胜感激。

5 个答案:

答案 0 :(得分:2)

继承将允许您不必重复代码。协议(其他编程语言称之为接口)实现OOP的Can-Do结构。当类实现协议时,该类表示它可以执行某些方法。仍然可以按照他们认为合适的方式来实现该方法。

以下是Apple的开发人员参考:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html

答案 1 :(得分:2)

协议是一组方法声明。它的主要目的是允许类之间的灵活关系。

假设我想要各种类发送日志消息,但我不希望他们负责知道消息发送后会发生什么。我创建了一个Logger协议,然后由ConsoleWriter类和DiskWriter类实现。想要发送消息的班级不知道或不关心它正在与哪个人交谈;它只是谈到它所知道的id<Logger>

答案 2 :(得分:1)

我不知道你有哪些类型的语言。但是Object-C协议非常像.NET中的接口。它的目的是定义一个契约(接口,足迹等),以便不必知道对象的实际“类型”,而只需知道它可以做什么。

话虽这么说,你可以定义一个具有一些属性和方法的协议“MyProtocol.h”。然后,您可以在类上实现此协议。您不需要在类的标题中添加协议的成员,只需要在实现中编写具体的实现。

这样做是允许您通过定义的接口而不是它们的类型来引用对象。因此,您可以使用id类型而不是实际的类类型。

希望这有帮助。

答案 3 :(得分:1)

协议几乎就像一个可移植的头文件。它们描述了可以或应该由符合协议的任何类实现的方法。这与继承不同,其中子类自动实现其超类的方法,并且可以选择在子类的基础上覆盖这些方法。

我怀疑你有一些OOP背景所以我不会过多地进行子类化,除了说子类通常是超类的专用或更具体的版本。换句话说:每个子类都是它的一个超类,但每个超类都不一定是一个子类。

ObjC中的协议通常用于委托模式,其中ClassA需要知道ClassB可以执行某种操作。这是一个例子:

// ClassA.h
#import "ClassB.h"

@interface ClassA <ClassBProtocol>
// Some variables
@end

// ClassA.m
@implementation ClassA
- (id)init {
    if ( (self = [super init]) ) {
        ClassB *classB = [[ClassB alloc] init]; // Create an instance of ClassB
        classB.delegate = self; // Set ourself as the delegate which means we want ClassB to tell us what to do
    }
    return self;
}

// Introduced by ClassBProtocol
- (void)doSomethingCoolWithString:(NSString *)string {
    // Do something here, it's up to ClassA what to do
}
@end


// ClassB.h
@protocol ClassBProtocol <NSObject>
- (void)doSomethingCoolWithString:(NSString *)string;
@end


@interface ClassB
@property (nonatomic, weak) id <ClassBProtocol>delegate;
// Some variables
@end


//ClassB.m
@implementation ClassB
@synthesize delegate;

- (id)init {
    if ( (self = [super init]) ) {
        if (delegate && [delegate respondsToSelector:@selector(doSomethingCoolWithString:)]) {
            [delegate doSomethingCoolWithString:@"A String"];
        }
    }
    return self;
}
@end

答案 4 :(得分:-1)

以下简单协议示例&amp;属性:

---&GT; ViewController.h文件

#import <UIKit/UIKit.h>
#import "MyVC.h"

@interface ViewController : UIViewController<MyVCProtocol>
{
    IBOutlet UILabel *label;
    IBOutlet UIButton *btnPush;
    MyVC *vc;
}
-(IBAction)Buttonclicked;
@end

---&GT; ViewController.m文件

#import "ViewController.h"

@implementation ViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(IBAction)Buttonclicked
{
    vc = [[MyVC alloc]initWithNibName:@"MyVC" bundle:nil];
    vc.delegate=self;
    [self.navigationController pushViewController:vc animated:YES];
}

-(void)GetText:(NSString *)text
{
    label.textAlignment=UITextAlignmentCenter;
    label.text=text;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

---&GT; MyVC.h文件

#import <UIKit/UIKit.h>

@protocol MyVCProtocol <NSObject>

-(void)GetText:(NSString *)text;

@end

@interface MyVC : UIViewController
{
    IBOutlet UITextField *m_TextField;
    IBOutlet UIButton *m_Button;
    id <MyVCProtocol> delegate;
}
@property(nonatomic, retain)id <MyVCProtocol> delegate;
-(IBAction)ButtonClicked;
@end

---&GT; MyVC.m文件

#import "MyVC.h"

@implementation MyVC
@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(IBAction)ButtonClicked
{
    [delegate GetText:m_TextField.text];
    [self.navigationController popViewControllerAnimated:YES];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end