类的扩展(二):类目、延展、协议和代理

定义方法:在 .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]




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值