OutMan——Objective-C中分类、延展、非正式协议和协议

分类(category:分类、类别、类目)

一、分类的作用
        分类的作用是:在不改变原来类的基础上,可以增加一些方法

二、分类的使用注意
1. 分类只能增加方法,不能增加成员变量(也不能使用@property生成原来类中没有的成员变量)
2. 分类方法实现中可以访问原来类中声明的成员变量
3. 分类可以重新实现原来类中的方法,但会覆盖掉原来的方法,会导致原来的方法没法再使用
4. 方法调用的优先级:分类(最后参与编译的分类优先)—>原来类—>父类
5. 分类增加的方法能被子类继承

三、如何给某个类分类
这里写图片描述
这里写图片描述

四、使用分类的目的
1. 对现有的类进行扩展:比如你可以扩展Cocoa touch框架中的类,你在分类中增加的方法会被子类继承,而且在运行时跟其他方法没有区别
2. 作为子类的代替手段:不需要定义和使用一个子类,可以通过分类直接向已有的类里增加方法
3. 对类中的方法归类:利用分类把一个庞大的类划分为多个小块来分别进行开发,从而更好的对类中方法进行更新和维护

五、分类的代码分析
(1)Person类的设计
                                                                     Person.h文件


#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
}
@property int age;   // 年龄

// run方法的声明
- (void)run;
// test方法的声明
- (void)test;

@end

                                                                     Person.m文件


#import "Person.h"

@implementation Person
// run方法的实现
- (void)run
{
    NSLog(@"%d岁的人在奔跑", _age);
}

// test方法的实现
- (void)test
{
    NSLog(@"Person----->test");
}
@end

(2)Person类的分类Person+Eat类的设计
                                                                     Person+Eat.h文件


#import "Person.h"

@interface Person (Eat)

// eat方法的声明
- (void)eat;

@end

                                                                     Person+Eat.m文件


#import "Person+Eat.h"

@implementation Person (Eat)
// eat方法的实现
- (void)eat
{
    NSLog(@"%d岁的人在吃东西", _age);
}

// test方法的实现
- (void)test
{
    NSLog(@"Person+Eat----->test");
}
@end

(3)Person类的分类Person+Jump类的设计
                                                                     Person+Jump.h文件


#import "Person.h"

@interface Person (Jump)

// jump方法的声明
- (void)jump;

@end

                                                                     Person+Jump.m文件


#import "Person+Jump.h"

@implementation Person (Jump)
// jump方法的实现
- (void)jump
{
    NSLog(@"%d岁的人在跳", _age);
}

// test方法的实现
- (void)test
{
    NSLog(@"Person+Jump----->test");
}
@end

(4)main.m文件
这里写图片描述
-设计注意:
1. 分类可以重新实现原来类中的方法,但会覆盖掉原来的方法,会导致原来的方法没法再使用
2. 当调用[p test]的时候,为什么打印的是Person+Eat—–>test?
方法调用的优先级:分类(最后参与编译的分类优先)—>原来类—>父类
3. 如何查看编译顺序
这里写图片描述
        从图中可以看出,最后参与编译的分类是Person+Eat这个分类,所以当调用[p test]的时候,打印的是Person+Eat—–>test

延展(扩展、延展类别)

一、延展的概念
        延展类别称为扩展(Extension)又称为延展,延展(Extension)是分类(category)的一个特例,其名字为匿名(为空),并且新添加的方法一定要予以实现(分类则没有这个限制)
        延展其实就是特殊的分类,这种写法的分类也叫匿名分类,所谓的延展,其实就是为一个类添加额外的原来没有的变量、方法或合成属性

二、延展的特点
1. 可以在延展中定义成员变量
2. 不能使用@implementation 类名()实现延展的方法
3. 可以在延展中定义私有的成员变量和方法

三、如何给某个类延展
这里写图片描述
这里写图片描述

四、延展和分类的区别
1. 分类中只能增加方法
2. 延展中不仅可以增加方法,还可以增加成员变量(或者合成属性),只是该变量默认是私有类型的(作用范围只能在自身类,而不是子类或其他地方)
3. 延展中声明的方法没有被实现,编译器会报警告,但是分类中的方法没有被实现,编译器是不会有任何警告的,这是因为延展是在编译阶段被添加到类中,而分类实在运行时添加到类中
4. 延展不能像分类那样,拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现
5. 定义在.m文件中的延展方法为私有的,定义在.h文件中的延展方法为公有的,延展是在.m文件中声明私有方法的非常好的方式

五、延展的代码实现
(1)Person类的设计
                                                                     Person.h文件


#import <Foundation/Foundation.h>

@interface Person : NSObject

@property int age;   // 年龄

// run方法的声明
- (void)run;

@end

                                                                     Person.m文件


#import "Person.h"
#import "Person_Eat.h"

@implementation Person
// run方法的实现
- (void)run
{
    NSLog(@"%d岁的人在奔跑", _age);
}

// eat方法的实现
- (void)eat
{
    NSLog(@"名字是%@,%d岁的正在吃", _name, _age);
}

@end

(2)Person类的延展Person_Eat类的实现
                                                                     Person+Eat.h文件


#import "Person.h"

@interface Person ()

@property NSString *name;   // 姓名

// eat方法的声明
- (void)eat;

@end

(3)main.m文件
这里写图片描述
-设计注意:
1. 延展中不仅可以增加方法,也可以增加成员变量或者合成属性),只是该变量默认是私有类型的(作用范围只能在自身类,而不是子类或其他地方)

非正式协议

一、非正式协议概念
        所谓的非正式协议:凡是NSObject的分类或其子类Foundation框架中的类的分类,都是非正式协议

二、非正式协议的实现代码:
        设计要求:给NSString增加一个类方法,计算某个字符串中阿拉伯数字的个数,给NSString增加一个对象方法,计算某个字符串中阿拉伯数字的个数
(1)非正式协议的设计
                                                                     NSString+CountNumber.h文件


#import <Foundation/Foundation.h>

@interface NSString (CountNumber)
// 计算字符串中数字个数方法的声明
+ (int)countNumber:(NSString *)aString;

// 计算字符串中数字个数方法的声明
- (int)countNumber;

@end

                                                                     NSString+CountNumber.m文件


#import "NSString+CountNumber.h"

@implementation NSString (CountNumber)
// 计算字符串中阿拉伯数字个数方法的实现
+ (int)countNumber:(NSString *)aString
{
    int count = 0;
    for(int i=0; i<aString.length; i++)
    {
        // 取出字符串中对应index位置的字符
        unichar c = [aString characterAtIndex:i];
        // 如果这个字符是阿拉伯数字
        if (c>='0' && c<='9')
        {
            count++;
        }
    }
    return count;
}

// 计算字符串中阿拉伯数字个数方法的实现
- (int)countNumber
{
    int count = 0;
    for(int i=0; i<self.length; i++)
    {
        // 取出字符串中对应index位置的字符
        unichar c = [self characterAtIndex:i];
        // 如果这个字符是阿拉伯数字
        if (c>='0' && c<='9')
        {
            count++;
        }
    }
    return count;
}
@end

(2)main.m文件
这里写图片描述
-设计注意:
1. for循环中,通过length方法来获取字符串的长度
2. 通过调用字符串的对象方法来获取对应index位置的字符,然后再进行判断当前字符是否是阿拉伯数字
3. if (c>=’0’ && c<=’9’)中‘0’和‘9’必须要加单引号,不加单引号是ASCII码值0和9,而不是字符0和9

协议

一、基本用途
1. 可以用来声明一大堆方法(不能声明成员变量)
2. 只要某个类遵守了这个协议,就相当于拥有了这个协议中所有的方法声明
3. 只要父类遵守了某个协议,就相当于子类也遵守了

二、格式
(1)协议的编写
@protocol 协议名称
// 方法列表
@end
(2)某个类遵守协议
@interface 类名:父类<协议名称>
@end

三、如何创建协议
这里写图片描述
这里写图片描述

四、协议中的关键字
        协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
@required:这个方法必须要实现(若不实现,编译器会发出警告)
@optional:这个方法不一定要实现

五、协议之间的遵守、基协议
(1)协议遵守协议
1. 一个协议可以遵守其他多个协议,多个协议之间用逗号隔开
2. 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
3. 格式:
@protocol 协议名称<协议1,协议2…>
@end
(2)基协议
1. NSObject是一个基类,最根本的类,任何其他类都最终要继承它
2. 其实还有个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
3. NSObject协议中声明了很多最基本的方法,比如description、retain、release等
4. 建议每个新的协议都要遵守NSObject协议

六、Protocol限制对象类型
(1)要求obj保存的对象必须是遵守MyProtocol这个协议

NSObject<MyProtocol> *obj = [[Person alloc] init];

(2)要求obj保存的对象必须遵守MyProtocol协议并且继承了Person类

Person<MyProtocol> *obj = [[Person alloc] init];

七、协议的提前声明
1. @protocol 协议名称;提前声明
2. 当使用到这个协议里面的东西的时候,再#import这个协议的头文件
3. 在mian.m文件中调用协议中的方法时,也需要#import这个协议的头文件

八、协议的代码实现
(1)RunProtocol协议的设计
                                                                     RunProtocol.h文件


#import <Foundation/Foundation.h>

@protocol RunProtocol <NSObject>

// run方法的声明
- (void)run;

@end

-设计注意:
1. 协议中的方法声明默认是@required(需要实现的)

(2)JumpAndSingProtocol协议的设计
                                                                     JumpAndSingProtocol.h文件


#import <Foundation/Foundation.h>

@protocol JumpAndSingProtocol <NSObject>

@required
// jump方法的声明
- (void)jump;
@optional
// sing方法的声明
- (void)sing;

@end

-设计注意:
1. @required:这个方法必须要实现(若不实现,编译器会发出警告)
2. @optional:这个方法不一定要实现

(3)EatProtocol协议的设计
                                                                     EatProtocol.h文件


#import <Foundation/Foundation.h>
#import "JumpAndSingProtocol.h"
#import "RunProtocol.h"

@protocol EatProtocol <NSObject, JumpAndSingProtocol, RunProtocol>

// eat方法的声明
- (void)eat;

@end

-设计注意:
1. 一个协议可以遵守其他多个协议,多个协议之间用逗号隔开
2. 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
3. 格式:
@protocol 协议名称<协议1,协议2…>
@end

(4)Person类的设计
                                                                     Person.h文件


#import <Foundation/Foundation.h>
#import "EatProtocol.h"

@interface Person : NSObject<EatProtocol>

@end

                                                                     Person.m文件


#import "Person.h"

@implementation Person
// eat方法的实现
- (void)eat
{
    NSLog(@"Person在吃");
}

// jump方法的实现
- (void)jump
{
    NSLog(@"Person在跳");
}

// run方法的实现
- (void)run
{
    NSLog(@"Person在跑");
}

@end

-设计注意:
1. @required:这个方法必须要实现(若不实现,编译器会发出警告)
这里写图片描述
2. @optional:这个方法不一定要实现(例:sing方法不实现也没有关系)

(5)main.m文件
这里写图片描述


                                        —— 如果您有不同的见解,请随时指出,期待与您的交流!——


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
这个错误是因为在插入数据时,使用了一个不正确的日期时间值。具体报错信息是1292 - Incorrect datetime value: '' for column 'createtime' at row 1。有几种可能的解决方案可以解决这个问题。 首先,你可以检查插入数据的日期时间格式是否符合数据库字段的要求。在MySQL,日期时间格式应该是'YYYY-MM-DD HH:MM:SS'的形式。如果日期时间值为空,你可以尝试使用NULL或默认值作为替代。 其次,你可以检查数据库表对应字段的数据类型是否正确。如果数据库表的字段类型是timestamp,可能会受到时间范围的限制。timestamp类型的截止时间是北京时间2038-1-19 11:14:07。如果你插入的日期超过了这个时间范围,你可能需要将字段的类型修改为DATETIME或者调整插入的日期时间值。 最后,你还可以检查数据库服务器的时区设置。时区的不匹配也可能导致日期时间值被认为是不正确的。确保数据库服务器的时区设置与你应用程序的时区设置保持一致。 综上所述,解决这个错误的方法包括检查日期时间格式、检查字段类型、调整日期时间值以及检查时区设置。根据具体情况选择适合的解决方案即可解决这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [1292 - Incorrect datetime valuemysql插入非法的时间数据解决方案](https://blog.csdn.net/outman_1921/article/details/106728315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Mysql报错:1292 - Incorrect datetime value for column create_time at row 1 解决方案](https://blog.csdn.net/guo_qiangqiang/article/details/123728655)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值