1.协议
1.协议是一种要求,或者一种规则
2.对程序来讲,是只声明,不实现
3.协议必须被某个类采纳且在该类中给出协议中方法的函数体
4.对于采纳协议的类,可以和其他类一样使用
建一个协议MyProtocol
.h文件
#import <Foundation/Foundation.h>
@protocol CZMyProtocol <NSObject>
@property NSString *content; //协议中定义的属性
-(void)show; //协议中定义的方法
@end
建一个类MyClass
.h文件
#import <Foundation/Foundation.h>
#import "CZMyProtocol.h" //要包含协议文件
@interface CZMyClass : NSObject<CZMyProtocol> //需要采纳协议
@end
.m文件
#import "CZMyClass.h"
@implementation CZMyClass
@synthesize content = _content;
-(void)show //在类中实现协议中的方法
{
NSLog(@"秀一下,%@", self.content);
}
@end
main函数
#import <Foundation/Foundation.h>
#import "CZMyClass.h"
#import "CZClassA.h"
#import "CZClassB.h"
#import "CZClassC.h"
void test1()
{
CZMyClass *obj = [[CZMyClass alloc] init];
obj.content = @"协议中的属性";
[obj show];
id<CZMyProtocol> id1 = obj; //id只能调用该协议中的方法
id1.content = @"万能指针使用属性";
[id1 show];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test1();
}
return 0;
}
运行结果
2016-08-25 20:40:04.399 day17_05[5300:344831] 秀一下,协议中的属性
2016-08-25 20:40:04.400 day17_05[5300:344831] 秀一下,万能指针使用属性
Program ended with exit code: 0
5.协议可以继承,包括多个父协议
#import "CZProtocol2.h"
#import "CZProtocol3.h"
@protocol CZProtocol4 <CZProtocol2,CZProtocol3>
@end
数组协议多态
void test5()
{
id<CZProtocol2> b[2];
b[0] = [[CZClassA alloc] init];
b[1] = [[CZClassB alloc] init];
for (int i = 0; i < 2; i++)
{
[b[i] method1];
}
}
参数协议多态
void fun(id<CZProtocol2> a)
{
[a method1];
}
void test6()
{
CZClassA *objA = [[CZClassA alloc] init];
fun(objA);
CZClassB *objB = [[CZClassB alloc] init];
fun(objB);
}
返回值协议多态
typedef enum
{
CLASSA, CLASSB, CLASSC,
}Type;
id<CZProtocol2> get(Type type)
{
switch (type) {
case CLASSA:
return [[CZClassA alloc] init];
case CLASSB:
return [[CZClassB alloc] init];
case CLASSC:
return [[CZClassC alloc] init];
}
}
void test7()
{
[get(CLASSA) method0];
[get(CLASSB) method0];
}
2.分类
2.1.将一个复杂的类分成若干个模块,其中每个模块被称为一个分类,
2.2.分类的作用是降低耦合度
2.3.分类的语法
2.4.在主函数中只能看到一个主类,不会看到分类
2.5.分类中不能定义成员变量或属性
2.6.可以给没有源代码的类添加分类,分类的方法不能跟主类的方法同名
建一个主类Fraction
.h文件
#import <Foundation/Foundation.h>
@interface CZFraction : NSObject
@property int n;
@property int d;
-(void)show;
@end
.m文件
#import "CZFraction.h"
@implementation CZFraction
-(void)show
{
NSLog(@"%d/%d", self.n, self.d);
}
@end
建一个Init分类
.h文件
#import "CZFraction.h"
//分类写主类的初始化方法
@interface CZFraction (CZInit)
-(id)initWithN:(int)n andD:(int)d; //分类中只能定义方法
+(id)fractionWithN:(int)n andD:(int)d;
@end
.m文件
#import "CZFraction+CZInit.h"
@implementation CZFraction (CZInit)
-(id)initWithN:(int)n andD:(int)d
{
if (self = [super init])
{
self.n = n;
self.d = d;
}
return self;
}
+(id)fractionWithN:(int)n andD:(int)d
{
CZFraction *f = [[CZFraction alloc] initWithN:n andD:d];
return f;
}
@end
再写一个Math分类
.h文件
#import "CZFraction.h"
//分类写math功能的方法
@interface CZFraction (CZMath)
-(CZFraction*)add:(CZFraction*)f;
-(CZFraction*)sub:(CZFraction*)f;
-(CZFraction*)mul:(CZFraction*)f;
-(CZFraction*)div:(CZFraction*)f;
@end
.m文件
#import "CZFraction+CZMath.h"
#import "CZFraction+CZInit.h"
@implementation CZFraction (CZMath)
-(CZFraction *)add:(CZFraction *)f
{
CZFraction *result = [[CZFraction alloc] init];
result.n = self.n * f.d + f.n * self.d;
result.d = self.d * f.d;
return result;
}
-(CZFraction *)sub:(CZFraction *)f
{
int n = self.n * f.d - f.n * self.d;
int d = self.d * f.d;
return [CZFraction fractionWithN:n andD:d];
}
-(CZFraction *)mul:(CZFraction *)f
{
return [CZFraction fractionWithN:self.n *f.n andD:self.d * f.d];
}
-(CZFraction *)div:(CZFraction *)f
{
return [CZFraction fractionWithN:self.n *f.d andD:self.d * f.n];
}
@end
main函数
#import <Foundation/Foundation.h>
#import "CZFraciom+CZInit.h"
#import "CZFraciom+CZMath.h"
#import "CZFraciom+CZTransfer.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
CZFraciom* f1=[CZFraciom fractionWithN:3 andD:4];
CZFraciom* f2=[CZFraciom fractionWithN:1 andD:2];
[f1 add:f2];
[f1 show];
[f1 sub:f2];
[f1 show];
[f1 mul:f2];
[f1 show];
[f1 div:f2];
[f1 show];
3.扩展
2.1 扩展是没有名字的分类
2.2 两种形式
2.2.1 单独写在一个.h文件中,扩展中的成员变量是私有的,属性和方法是公有的
2.2.2 写在主类中的.m文件,扩展中的成员变量,属性,方法都是私有的
2.3 与分类的区别
2.3.1 有没有.m文件
2.3.2 有没有成员变量或属性
2.4 与协议区别:协议可以被任何类采纳,但扩展只能属于主类
建一个扩展文件
#import "CZFraction.h"
@interface CZFraction ()
{
int _a; //默认私有
@public
int _b;
}
-(void)extensionMethod0;
@end
扩展写在类的.m文件中
#import "CZFraction.h"
#import "CZFraction_CZMyExtension.h"
//写在.m文件中的扩展一般用于声明私有方法,方便程序员查看
@interface CZFraction() //扩展写在.m文件中的时候,属性和方法都是私有的
@property int value; //私有
-(void)extensionMethod1;//私有
@end
@implementation CZFraction
-(void)show
{
NSLog(@"%d/%d",self.n,self.d);
}
-(void)extensionMethod0 //私有方法
{
NSLog(@"这是扩展中的方法");
}
-(void)extensionMethod1
{
NSLog(@"主类中.m文件中的方法");
}
@end