• 《objective-c基础教程》学习笔记(十一)—— 类别


      在编写面向对象程序的时候,我们经常想为现有的类添加一些新的行为。有些时候,我们可以创建这个类的子类。但是,如果我们用到工具集或者类库的时候,无法处理新建的子类。这时,Objective-C就给我们提供了一个非常方便好用的方式 —— 类别(category)。

      那么,什么是类别呢?类别是一种为现有的类添加新方法的方式。你只需要知道这个类的公开接口,不需要知道类的源代码。而且可以将类定义模块化地分布到多个相关文件中。

      类别同样由声明部分和实现部分组成,声明部分语法格式如下:

    1 @interface 已经存在的类名 (类别名)
    2     // 方法定义
    3     ...
    4 @end

      类别实现部分的语法格式如下:

    1 @implmentation 已经存在的类名 (类别名)
    2     // 实现方法代码
    3     ...
    4 @end

      类别是Objective-C中一个非常重要的知识,它通常有如下3种用法:

    1). 利用类别对类进行模块化设计;
    2). 使用类别来调用私有方法;
    3). 使用类别来实现非正式协议。 

      下面,我们通过一个例子,给大家展示下如何来使用类别这个方式。就编程习惯而言,一般习惯将类别的接口文件名命名为“类名+类别名.h”的形式,实现部分文件则命名为“类名+类别名.m”。

      首先,我们创建一个名为:NSNumber+Calculate的类文件。创建好类文件,项目中会自动生成两个文件:

      接下来,我们就分别来写接口文件和实现文件的代码。

     1 //
     2 //  NSNumber+Calculate.h
     3 //
     4 
     5 #import <Foundation/Foundation.h>
     6 
     7 @interface NSNumber(Calculate)
     8     // 在类别中定义了4个方法
     9     -(NSNumber*) add: (double) num2;
    10     -(NSNumber*) substract: (double) num2;
    11     -(NSNumber*) multiply: (double) num2;
    12     -(NSNumber*) divide: (double) num2;
    13 @end

      实现部分代码:

     1 //
     2 //  NSNumber+Calculate.m
     3 //
     4 
     5 #import "NSNumber+Calculate.h"
     6 
     7 @implementation NSNumber(Calculate)
     8     // 实现类别的接口部分定义的4个方法
     9     -(NSNumber*) add: (double) num2
    10     {
    11         return [NSNumber numberWithDouble:([self doubleValue] + num2)];
    12     }
    13     -(NSNumber*) substract:(double)num2
    14     {
    15         return [NSNumber numberWithDouble:([self doubleValue] - num2)];
    16     }
    17     -(NSNumber*) multiply: (double) num2
    18     {
    19         return [NSNumber numberWithDouble:([self doubleValue] * num2)];
    20     }
    21     -(NSNumber*) divide: (double) num2
    22     {
    23         return [NSNumber numberWithDouble:([self doubleValue] / num2)];
    24     }
    25 @end

      最后,在main主函数中调用定义的方法,来测试下我们定义的类别方法是否能正常实现。

     1 //
     2 //  main.m
     3 //
     4 
     5 #import <Foundation/Foundation.h>
     6 #import "NSNumber+Calculate.h"
     7 
     8 int main(int argc, const char * argv[])
     9 {
    10 
    11     @autoreleasepool {
    12         NSNumber* myNum = [NSNumber numberWithInt:3];
    13         // 测试 add方法
    14         NSNumber* add = [myNum add:2.4];
    15         NSLog(@"Add: %@", add);
    16         // 测试 substract方法
    17         NSNumber* substract = [myNum substract:2.4];
    18         NSLog(@"Add: %@", substract);
    19         // 测试 multiply方法
    20         NSNumber* multiply = [myNum multiply:2.4];
    21         NSLog(@"Add: %@", multiply);
    22         // 测试 divide方法
    23         NSNumber* divide = [myNum divide:2.4];
    24         NSLog(@"Add: %@", divide);
    25     }
    26     return 0;
    27 }

      正常运行后的结果如下:

      虽然类别可以重写原有类中的方法,但通常不推荐这么做。如果需要重写原类的方法,更好的建议是通过原有类的派生类,然后再子类中重写父类的原有方法来实现。

      通过类别为指定类添加新方法之后,这个新方法不仅会影响NSNumber类,还会影响NSNumber类的所有子类,每个子类都会获取类别扩展的方法。同时,可以根据需要,为一个类定义多个类别,不同的类别都可以对原有的类添加方法定义。

      好了,类别的概念和基本的使用方法就介绍这么多。下一篇博文,我们将介绍另外几个在Objective-C中非常重要的:协议和委托。

  • 相关阅读:
    Bolero and Data Mining
    2007年3月15日 网站论坛出现以下错误/forum/inc/Dv_ClsMain.asp,行 1344
    A Probabilistic Model for Retrospective News Event
    信息抽取的资料文档
    Textual Data Mining and WEBSOM
    DockPanel Suite更新到2.6了 武胜
    Use Custom Events from your WCF ServiceHost http://www.codeproject.com/Tips/150702/UseCustomEventsfromyourWCFServiceHost 武胜
    Unable to convert MySQL date/time value to System.DateTime 解决方案 转 武胜
    XML 转义字符 武胜
    Using Nini .NET Configuration Library 武胜
  • 原文地址:https://www.cnblogs.com/jianglan/p/4170587.html
Copyright © 2020-2023  润新知