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

问题描述:

因此,我对objective-c相当陌生,并且试图围绕协议进行探讨。我将用一个例子来说明我的问题。协议和访问另一个类的方法

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

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

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

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

+1

你熟悉其他编程语言和他们使用的接口吗? –

继承将允许您不必重复代码。协议(其他编程语言称为接口)实现了OOP的Can-Do结构。当一个类实现一个协议时,这个类意味着它可以完成一些特定的方法。他们认为合适的方法实施该方法仍然取决于该班级。

下面是苹果开发者参考:

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

我不跟你有什么样的语言经验知道。但是Object-C协议非常像.NET中的Interface。它的目的是定义一个合约(界面,足迹等),以便不需要知道对象的实际“类型”,但是它可以做什么。

这就是说你可以定义一个协议“MyProtocol.h”,它有几个属性和方法。然后你可以在一个类上实现这个协议。您不需要在该类的头文件中添加协议的成员,只需在实现中编写具体的实现即可。

这样做可以让您通过其定义的接口引用对象而不是它们的类型。所以你可以使用id类型而不是实际的类类型。

希望这会有所帮助。

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

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

协议几乎就像一个可移植的头文件。他们描述了可以或应该由符合协议的任何类来实现的方法。这与继承的不同之处在于子类自动实现其超类的方法,并且这些方法可以通过子类可选地在子类上重写。

我怀疑你有一些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 

下面的例子:

---> ViewController.h文件

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

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

---> 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 

---> 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 

---> 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