定义方法:在 .h文件 和 .m文件的延展 中
实现方法:.m文件中
重写方法:父类有这个方法,子类重写这个方法
1. 类目(Category)
是用于分类使用,将一个类的不同功能的方法进行不同的分类
给一个类进行扩展,添加方法和属性
注意:
1) 类目中禁止写成员变量
2) 类目中可以写属性,但是实现麻烦(一般都不写属性)
3) 一般类目中创建方法
例子:对NSString进行扩展NSString+My.h文件
#import <Foundation/Foundation.h>
@interface NSString (My)
// 类目中禁止写成员变量
//{
// NSString *_str;
//}
// 类目中可以写属性,但是实现麻烦(一般都不写属性)
//@property (nonatomic, retain) NSString *str;
// 一般类目中创建方法
- (void)my;
// 获得字符串的最后一个字符
// 1.
- (NSString *)getLastText;
// 2.
//+ (NSString *)getLastWord:(NSString *)str;
@end
NSString+My.m文件
#import "NSString+My.h"
@implementation NSString (My)
- (void)my
{
NSLog(@"%s", __func__);
// 谁调用这个方法,self就是谁
NSLog(@"self = %@", self);
}
// 获得字符串的最后一个字符
// 1.
- (NSString *)getLastText
{
NSString *s = [self substringWithRange:NSMakeRange([self length] - 1, 1)];
return s;
}
// 2.
//+ (NSString *)getLastWord:(NSString *)str
//{
// NSString *s = [[str substringFromIndex:str.length - 1] substringToIndex:1];
// return s;
//}
@end
main 中
#import <Foundation/Foundation.h>
#import "NSString+My.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *str = @"12345";
[str my];
// 获取字符串最后一个字符
// 1.
NSLog(@"lastWord = %@", [str getLastText]);
// 2.
// NSLog(@"lastWord = %@", [NSString getLastWord:str]);
}
return 0;
}
打印结果:
lastWord = 5
2. 延展(extension)
延展主要是给类添加私有变量和私有方法,私有的变量和方法,在外部用不了
在 .m文件中@imlpementation上 写 @interface <#class name#> ()
中间写私有的变量和方法
@end
例子:
Car.h文件
#import <Foundation/Foundation.h>
@interface Car : NSObject
@end
Car.m文件
#import "Car.h"
// 延展主要是给类添加私有变量和私有方法
@interface Car ()// ()中不写内容
// 延展中可以写成员变量
{
NSString *_name;
}
// 延展中可以写属性
@property (nonatomic, retain) NSString *price;
// 延展中可以声明方法
- (void)info;
@end
@implementation Car
// 实现私有的方法
- (void)info
{
NSLog(@"%s", __func__);
}
@end
main 中
<span style="font-size:14px;">#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *car = [[Car alloc] init];
// 私有的变量和方法,在外部用不了
// car.name
// [car info];
}
return 0;
}</span>
3. 协议(Protocol)和代理人(Delegate)
3.1协议(Protocol)
是一堆公共方法名的集合,只有.h文件,没有.m文件
只声明方法,谁遵循这个协议,谁来实现协议中的方法
例子:girl:饿了,提出要求:做饭(必须的)、吃(可选的)
people:签订协议,给女孩做饭吃
1). 声明协议 (MyProtocol.h)
2). 设置代理人属性 (Girl.h)
3). 让代理人调用方法 (Girl.m)
4). 签订协议 (People.m)
5). 指定代理人 (main.m)
6). 实现协议 (People.m)
MyProtocol.h文件
#import <Foundation/Foundation.h>
// 1. 声明协议
@protocol MyProtocol <NSObject>
// 只声明方法,谁遵循这个协议,谁来实现协议中的方法
// 必须实现的
@required
- (void)cook;
// 可选的
@optional
- (void)eat;
@end
3.2 代理人(Delegate)例子:
People.h文件
#import <Foundation/Foundation.h>
// 引入协议.h文件,只有协议 被引入是在 .h中 写#import,其他的写@class
#import "MyProtocol.h"
// 4. 签订协议
@interface People : NSObject <MyProtocol>
@end
People.m文件
#import "People.h"
@implementation People
// 6. 实现协议
- (void)cook
{
NSLog(@"%s", __func__);
}
@end</span>
注:
不管cook这个方法在哪里定义的,只要在哪个类中实现,那么这个方法就属于这个类
不管哪个类,只要实现它签订的协议中的方法,这个方法就属于这个类,只能这个类的对象来调用这个方法
Girl.h文件
#import <Foundation/Foundation.h>
// 引入协议.h文件
#import "MyProtocol.h"
@interface Girl : NSObject
// 2. 设置代理人属性
@property (nonatomic, assign) id<MyProtocol> delegate;// 设置代理人属性使用assgin
- (void)hungry;
@end
Girl.m文件
#import "Girl.h"
@implementation Girl
- (void)hungry
{
// 3. 让代理人调用方法
[self.delegate cook];
}
@end
main 文件
#import <Foundation/Foundation.h>
#import "Girl.h"
#import "People.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
People *p = [[People alloc] init];
Girl *g = [[Girl alloc] init];
// 5. 指定代理人
g.delegate = p;
// 6. 实现协议
[g hungry];
}
return 0;
}
打印结果:
-[People cook]