作者:韩俊强
总结以往方法: 继承是可以完成对类型的扩充,不仅能添加方法,也可以添加实例变量;/缺点:如果工程中有很多需要扩充类的使用,此时要用子类去完成替换,工作量非常大,还容易出错。下面通过例子过渡一下进入类的扩展!
==============================================================
 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];

}

@end
main.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;

@end
Person+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;

@end
NSString+Say.m
@implementation
NSString
(SayHi)

- (void)sayHi{

NSLog(@"你好
我是5号");

}
//拼接字符串的方法

- (NSString
*)appendingString
: (NSString
*)string{

return
[string
stringByAppendingString:@"约嘛?"];

}

@end
main.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;
@end
NSDate+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];

}

@end
main.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;
@end
Dog.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;//吃骨头
@end
main.m
Dog
*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;

@end
Girl.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];

}

@end
GirlDelegate.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;

@end
Boy.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(@"你看我长得像不像周润发?");

}

@end
main.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];
欢迎阅读本文,转载分享请注明出处!

Category&nbsp;Protocol&nbsp;Exte…的更多相关文章

  1. objective c, category 和 protocol 中添加property

    property的本质是实例变量 + getter 和 setter 方法 category和protocol可以添加方法 category 和 protocol中可以添加@property 关键字 ...

  2. 设计模式之开放-封闭原则(引申出Objective-C中继承、Category、Protocol三者的区别,这点面试常问)

    开放封闭原则(OCP原则The Open-Closed Principle)是面向对象的核心设计所在.它是说,软件开发实体(类.模块.函数等)应该可以扩展,但是不能修改. 这个原则有两个特征,一个是说 ...

  3. 04OC之分类Category,协议Protocol,Copy,代码块block

    一.Protocol协议 我们都知道,在C#有个规范称之为接口,就是规范一系列的行为,事物.在C#中是使用Interface关键字来声明一个接口的,但是在OC中interface是用来声明类,所以用了 ...

  4. ios category,protocol理解

    category: 向现有的类中增加方法,同时提供方法的实现,现有类不需要做任何改动. protocol:(相当于Java或C#中的接口interface,当很多类都要需要类似的方法,但是方法具体实现 ...

  5. iOS的category和protocol

    很多时候我们需要扩展一下现有的类,增加一点功能.如果有源码,修改一下即可,如果是第三方的库,就要麻烦一些.在C++中我们使用类继承的方法来实现,在ObjectiveC中当然也可以这么做,不过Objec ...

  6. Objective-C——消息、Category和Protocol

    转自:http://www.cnblogs.com/chijianqiang/archive/2012/06/22/objc-category-protocol.html 面向对象永远是个可以吐槽的话 ...

  7. xcode 在哪里新建category、protocol等文件

    1.和以前新建新文件一样.2.当然选IOS啦,不过OS X也有这个选项,然后Objctive-C File. 3.在File Type里选就OK啦.

  8. oc中protocol、category和继承的区别

    OC中protocol.category和继承的区别以前还是有点迷糊,面试的时候说的有点混乱,现在结合一些资料总结一下. 利用继承,多态是一个很好的保持"对扩展开放.对更改封闭"( ...

  9. Objective-C-----协议protocol,代码块block,分类category

    概述 ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,本文将重点介绍objective-C中一些常用的语法特性. 当然这些内容虽然和其他高级语言 ...

随机推荐

  1. SpringMVC 教程 - Handler Method

    原文链接:https://www.codemore.top/cates/Backend/post/2018-04-21/spring-mvc-handler-methods 由注解@RequestMa ...

  2. Node.js 网络

    稳定性: 3 - 稳定 net 模块提供了异步网络封装,它包含了创建服务器/客户端的方法(调用 streams).可以通过调用 require('net') 包含这个模块. net.createSer ...

  3. J-Link固件烧录以及使用J-Flash向arm硬件板下载固件程序

    这篇文章的最初版本是在15年写的https://blog.csdn.net/u010592722/article/details/45575663,后来又遇到了一些新问题,故更新在了这里. 一.始于安 ...

  4. 这交互炸了(四) :一分钟让你拥有微信拖拽透明返回PhotoView

    本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发 <交互炸了>或许是一系列高端特效教程, 文中会介绍一些比较炫酷的特效,以及实现的思路.特效实现本身也许不会有太大的难度 ...

  5. springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)

    在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...

  6. 手势监听GestureDetector 案例

    以下只做长按和甩出(用户按下朝某一方向甩动手指)案例 OnGestureListener可以查看到更多的手势事件 案例 package com.qf.mobliesafe.activity; impo ...

  7. Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...

  8. AJAX编程实践

    ---------------------------------------------------------------------------------------------------- ...

  9. how to output quotes in bash prompt

    introduction In certain situations, quotes are required to be output in the command prompt. To do th ...

  10. Ribbon WorkBench 当ValueRule的值为空时的设置

    在定制Ribbon按钮的规则的时候,有时需要根据某个字段值是否为空不设定Ribbon按钮的Display rules或Enable Rules,根据Crm的版本的不同,设置有所差别: 对于Dynami ...