作者:韩俊强总结以往方法: 继承是可以完成对类型的扩充,不仅能添加方法,也可以添加实例变量;/缺点:如果工程中有很多需要扩充类的使用,此时要用子类去完成替换,工作量非常大,还容易出错。下面通过例子过渡一下进入类的扩展!============================================================== 1.例子:通过继承完成类的扩展Person.h@interface
Person
: NSObject
{
NSString
*_name;
NSInteger
_age;
//添加新实例变量
NSString
*_sex;
}
– (void)sayHi;
//给类添加新方法-
(void)sayHello;
Person.m//这是延展,此时的延展不需要创建.h文件,直接将延展写到类的.m文件中
//建议以后写延展都是用这种方式
//延展方便我们管理一个类的私有方法和实例变量
@interface
Person
()
{
NSString
*_hobby; }-
(void)dance;@end@implementation
Person
//延展的实现部分-
(void)dance{
NSLog(@”———–跳舞真好”) ;
}-
(void)sayHi{
NSLog(@”你好
包小姐!”);}
//给类添加新方法
– (void)sayHello{
NSLog(@”Hello
包小姐!”);
//调用延展里声明的方法
[self
dance];
}
@endmain.m//如何为Person这个类添加方法
Person
*p
= [[Person
alloc]init];
[p
sayHi];
[p sayHello];
Student
*p1 =
[[Student
alloc]init];
[p1 study];
//调用分类的方法
(知道源文件情况)
[p1 hitPlan];======================================================在上题中我们扩展一个Category 类的扩展:2、使用Category 分类或类目
主要作用是为没有源代码的类添加方法,禁忌:使用Category
给类添加方法可以,但是不能添加实例变量 **添加分类的步骤:
//1.新建文件 command +
n
//2.选择Object-c
File模板
//3.File栏根据扩展的功能写入文件名
//4.中间栏选择Category
//5.Class选项写入对那个类的扩充,就写入那个类的类名
//6.next之后会自动生成一对“类名 +
扩展名.h”和“类型加扩展名.m”文件
//7.在.h写入方法声明,在.m中写方法实现Person+Study.h//小括号代表某个类的分类
//(分类名)
@interface
Person
(Study)
{
//
NSString *_color;
error!!!实例变量不能定义到分类中
}
//分类不仅可以添加类方法也可以添加对象方法
//类方法
+ (void)study;
//对象方法
– (void)study;
– (void)sayHi;
@endPerson+Study.m@implementation
Person
(Study)
//类方法
+ (void)study{
NSLog(@”学习LOL包小姐”);
}
//对象方法
– (void)study{
NSLog(@”学习CF包小姐”);
}
– (void)sayHi{
NSLog(@”你好,苹果”);
}
@end
Student.h@interface
Student
: Person
{
NSInteger
_number;
}-
(void)study;@end
//不正式添加分类的方法@interface Student
(hitPlan)-
(void)hitPlan;@end
Student.m@implementation
Student
– (void)study{
NSLog(@”努力学习包小姐”);
}
@end
@implementation
Student
(hitPlan)
//分类的实现
这种方式只适合能看到源文件的类
– (void)hitPlan{
NSLog(@”打飞机”);
}
@end
main.m //使用Category
添加的方法,是直接作用到当前那个类上的,可以使用当前类或者当前类创建的对象直接调用方法
Person
*p2 =
[[Person
alloc]init];
[Person
study];
[p2
study];
//如果分类中定义和原始中一样的方法,此时优先选择执行分类中的方法
[p1 sayHi];
=====================================================3、 练习:为NSString
添加分类(类方法)NSString+Say.h@interface
NSString
(SayHi)
– (void)sayHi;
//拼接字符串的方法
– (NSString
*)appendingString
: (NSString
*)string;
@endNSString+Say.m@implementation
NSString
(SayHi)
– (void)sayHi{
NSLog(@”你好
我是5号”);
}
//拼接字符串的方法
– (NSString
*)appendingString
: (NSString
*)string{
return
[string
stringByAppendingString:@”约嘛?”];
}
@endmain.m
//为NSString
添加分类
NSString
*s
= [NSString
string];
[s
sayHi];
NSString
*newString
= [s appendingString:@”罗玉凤”];
NSLog(@”%@”,newString);======================================================4、练习: 为NSDate添加一个对象(对象方法)NSDate+Date.h@interface
NSDate
(Date)
+ (NSDate
*)dateWithDateString
: (NSString
*)dateString;@endNSDate+Date.m@implementation
NSDate
(Date)
+ (NSDate
*)dateWithDateString
: (NSString
*)dateString{
//日期格式对象
NSDateFormatter
*formatter =
[[NSDateFormatter
alloc]init];
//指定格式
[formatter setDateFormat:@”yyyyMMddHHmmss”];
NSDate
*date1 =
[formatter
dateFromString:dateString];
return
[date1
dateByAddingTimeInterval:8
*60
*60];
}
@endmain.m //准备时间字符串
NSString
*dateString
= @”20150907160230″;
NSDate
*date =
[NSDate
dateWithDateString:dateString];
NSLog(@”%@”,date);
———————————————————————-
总结 :
延展和分类的区别 1.延展中可以添加实例变量,分类中不可以
2.延展中的方法和实例变量都是私有的,不能直接访问,分类中的方法外界可以访问
3.延展针对是已知类(因为它的实现只能在这个类的.m文件中写),分类中可以为不知道源文件的类添加方法; 4.延展中的子类不能继承,而分类中的方法子类可以直接使用(私有方法下面Dog类会再做例子说明)======================================================5、代理模式(Delegate)解题思路: 协议和代理的使用 1.定义协议(协议中存放的是代理应该完成的方法) 2.定义代理实例变量(用来存储在外界设置的代理对象) 3.在.m文件中让_delegate执行协议中的方法,并且为这些方法设置触发的时机 4.在其他文件中指定代理对象,对象要遵循协议内容(答应去干活) 5.代理对象实现协议中的方法(知道怎么去干活) 6.指定协议方通知代理对象干活(让代理干活)
———————————————————————————– 6、****代理设计模式的步骤:
1.制订协议
2.找代理,遵循协议
3.成为代理
4.执行协议中的方法
=============制定协议的步骤:==============
1.Command + n 新建文件
2.文件名(类名 + delegate) eg: PersonDelegate
3.中间栏选Protocal
4.Class 哪个类指定的协议就写那个类
5.只生成.h文件
6.谁成为代理就去谁的.m文件写协议中方法实现例题: 创建一个Dog对象(模拟私有方法)Dog.h#import “Girl.h”@interface Dog : NSObject<</span>GirlDelegate>
//遵循GirlDelegate协议- (void)eatShit;@endDog.m#import
“Dog_Private.h”@implementation
Dog-
(void)eatShit{
_isTrue
=
YES;
if
(_isTrue)
{
//延展中的私有方法
[self
eatBone];
NSLog(@”躺着吃”);
}else{
NSLog(@”哈哈躺着吃啊”);
} }-
(void)eatBone{
NSLog(@”骨头真香啊”);
}
@end-
(void)wellDone
{
NSLog(@”你去找别人把”);}-
(void)makeMoney
{
NSLog(@”你把我卖了吧”);Dog_private.h@interface
Dog
()
{
BOOL
_isTrue;
}
– (void)eatBone;//吃骨头@endmain.mDog
*d
= [[Dog
alloc]init];
[d
eatShit];
[d eatBone];======================================================7、协议和代理模式例题:建立一个女孩找男朋友的征婚启事Girl.h#import
“GirlDelegate.h”
@interface
Girl :
NSObject
{
//设置一个男朋友的属性
//此时这个实例变量必须遵循协议
<协议名称>
//遵循协议符号
<协议名称>
id
<</span>GirlDelegate>_boyFriend;
NSString
*_name;
}
– (void)setName
: (NSString
*)name;
– (NSString
*)name;
//写setter
getter方法
– (void)setBoyFriend
: (id<</span>GirlDelegate>)boyFriend;
– (id<</span>GirlDelegate>)boyFriend;
– (void)wangShopping;
– (void)wantHappy;
– (void)wantFun;
– (void)wantEating;
@endGirl.m@implementation
Girl
– (void)setName:
(NSString
*)name{
_name
=
name;
}
– (NSString
*)name{
return
_name;
}
– (void)setBoyFriend
: (id<</span>GirlDelegate>)boyFriend{
_boyFriend
=
boyFriend;
}
– (id<</span>GirlDelegate>)boyFriend{
return
_boyFriend;
}
– (void)wangShopping{
if
([_boyFriend
respondsToSelector:@selector(makeMoney)])
{
[_boyFriend
makeMoney];
}else{
NSLog(@”出去卖切糕”);
}
}
– (void)wantHappy{
if
([_boyFriend
respondsToSelector:@selector(wellDone)])
{
[_boyFriend
wellDone];
}else{
NSLog(@”换人”);
}
}
– (void)wantEating{
//如果代理没有执行协议中的方法,此时加了这个判断就不会造成crash
if
([_boyFriend
respondsToSelector:@selector(cook)])
{
[_boyFriend
cook];
}else{
NSLog(@”自己做着吃”);
}
}
– (void)wantFun{
[_boyFriend
cook];
}
@endGirlDelegate.h 协议文件@protocol
GirlDelegate
<</span>NSObject>
@required
//required
修饰协议的内容是必须实现的
//能挣钱
– (void)makeMoney;
//能干
– (void)wellDone;
@optional
//optional
修饰协议 可选择实现的
//做饭
– (void)cook;
//幽默
– (void)humorous;
@end我们再定义一个接受女孩的一个男孩,男孩遵循协议并在Boy.m实现Boy.h#import
“GirlDelegate.h”
//一个类要想成为代理必须遵循协议,
协议的位置写在其父类的后面,使用一对尖括号<>
@interface
Boy :
NSObject<</span>GirlDelegate>
{
NSString
*_name;
}
– (void)setName
: (NSString
*)name;
– (NSString
*)name;@endBoy.m@implementation
Boy
– (void)setName
: (NSString
*)name{
_name
=
name;
}
– (NSString
*)name{
return
_name;
}
//实现协议中必须实现的方法
– (void)makeMoney
{
NSLog(@”一百万够不够花”);
}
– (void)wellDone
{
NSLog(@”一瓶伟哥够不”);
}
//实现协议中可选的方法
– (void)cook
{
NSLog(@”小鸡炖蘑菇”);
}
– (void)humorous
{
NSLog(@”你看我长得像不像周润发?”);
}
@endmain.m一天18岁的小樱决定结束自己18年的单身生活
Girl
*g
= [[Girl
alloc]init];
g.name
=
@”小樱”;
//于是它定义一个协议,心想,谁能完成协议,我当他女朋友
//此时25岁小军,下决定脱单,看到网上征婚协议
//一天后,鼓起勇气,小军看到协议,又摸了摸钱包,一咬牙签了
Boy
*b
= [[Boy
alloc]init];
b.name
=
@”小军”;
//签了协议就能成为小樱的男朋友
g.boyFriend
=
b;
//我想吃购物
[g
wangShopping];
//我想幸福
[g
wantHappy];
//我想开森
[g
wantFun];
//由于小军体能下降换男朋友(Dog)了
(和Dog例子调用蓝色部分)
Dog
*d1 =
[[Dog
alloc]init];
g.boyFriend
=
d1;
[g
wantHappy];
[g wangShopping];欢迎阅读本文,转载分享请注明出处!