利用继承,多态是一个很好的保持“对扩展开放、对更改封闭”(OCP)的办法,也是最常见的一种方法。Objective C还支持另外两种语法来支持OCP:Protocol和Category。Protocol只能定义一套接口,而不能提供实现,变相的也是一种Abstract class的实现方式(oc 语法上本身不支持抽象基类)。Category可以为类提供额外的接口和实现。那么到底三者(继承, Protocol,Category)在使用上到底有什么本质的区别呢?在我看来,protocol的作用是为一些列类仅仅提供一套公用的接口,而完全没 有办法也没可能去提供具体的一些实现情况;category则是为一个已有的类提供一些额外的接口和具体实现;而继承则基于两者之间,既可以想 protocol一样提供只是纯粹提供接口,也可以像Category一样提供完整的实现,而且继承还能对类以后的功能进行改写,所以说继承的力量是最强 大的。那么具体在使用的时候各自都适合什么样的情况呢?
        .        Protocol是定义行为而不管谁去怎么实现,这是一种比较洒脱和不负责的情况,就好像在外包项目中的客户一样,他只是他需要什么什么东西,具体实现他不会也不能给出一样。delegate datasource这样的就用protocol实现比较好
        .        Category是对一个功能完备的类的一种补充,就像是一个东西的主要基本功能都完成了,可以用category为这个类添加不同的组件,使得 这个类能够适应不同情况的需求(但是这些不同需求最核心的需求要一致)。找个就像你已经有了一辆能够开动的汽车一样,我们可以用Category为你的汽 车添加各种之前没有的功能,最后让这辆汽车变成超级跑车一样。
        .        当某个类非常大的时候,Category可以按不同的功能将类的实现分在不同的模块中实现。
        .        继承则是都可以完成上面的工作,但是继承有很大的代价问题,一是通过继承来进行扩展是一种耦合很高的行为,对父类可以说是完全依赖;二是继承由于 对父类依赖,所以开发代价相对大,要求对父类的工作流程相对熟悉;三是继承体系如果太复杂会导致整个系统混乱,难以维护。所以在能够用上面两种方法完成扩 展的时候,就千万不要使用继承。什么情况才是迫不得已要使用继承呢?那就是如果你既想提供一系列接口的定义,同时又想提供一些但是又不能提供全部的实现的 时候,这种情况就要使用继承了。所以这么看来继承是对上面两种功能的一个黏合剂。
关于category的另外一些见解:
        .        虽然category可以访问类的实例变量,去不能创建新的实例变量,如果要创新的实例变量,请使用继承;
        .        在category中,不提倡对原有方法进行重载。原因非常简单,在category中进行重载,无法对原方法进行访问,而继承中可以使用super。如果真的需要对原方法进行重载,请考虑继承,比如我要定义一个继承自UIViewController的类,就不能用Category,因为,这我定义的这个类中,我要实现UIViewController中的viewDidLoad、init等方法,用了category后父UIViewController中的这些方法将无法被调用;
        .        一个类可以定义多个category,但是如果不同category中存在相同方法,编译器无法决定使用哪个category;
        .        在定义category时,我们可以仅仅给出方法定义,而不需要给出具体的实现。这在程序增量开发时是非常有帮助的;
        .        category是可以被继承的。在某个父类中定义了category,那么他所有的子类都具有该category;
        .        在需要为某个类创建私有成员方法时,也用category的方式来实现。
Category不能完全代替子类,有以下几个最大的缺点:
        .        当在Category中覆盖一个继承的方法,在Category中的方法可以通过向super类发送一个消息来调用被继承的方法。但是,如果Category中覆盖的那个方法已经在这个类的其它Category定义过了,则之前定义的方法将没有机会被程序调用
        .        在Category中无法确定其能够可靠的覆盖某个方法,而这个方法已经在其它的Category中定义过。这个问题在使用Cocoa框架时尤其 突出。当你想覆盖某个框架已经定义好的方法时,该方法已经在其它Category中实现,这样就无法确定哪个定义和实现会被最先使用,带来很大的不确定 性。
        .        如果你重新覆盖定义了一些方法,往往会导致这个方法在整个框架中实现发生了变化。举例来说,如果你增加了NSObject中 windowWillClose:的实现,这会导致所有的窗口调用那个新实现的方法,从而改变所有NSWindows实例的行为。这会带来很多不确定性, 并很有可能导致程序的崩溃。

转载于:https://www.cnblogs.com/yuyu-2012/p/4728703.html

OC中protocol、category和继承的区别相关推荐

  1. Java中实现接口与继承的区别

    ** Java中实现接口与继承的区别 ** 首先,先来了解一下什么是接口和继承.接口一般是使用interface来定义的.接口定义同类的定义类似,分为接口的声明和接口体,其中接口体由常量定义和方法定义 ...

  2. CSS中100%和inherit(继承)的区别,以及inherit的简单应用

    CSS中100%和inherit(继承)的区别 正常情况下没有区别 兼容性 100% ie6+ inherit ie8+ 该元素绝对定位,父元素使用静态定位(static)或没有使用定位时 100%继 ...

  3. Object-C中的Category

    Object-C中的Category其实是一种对于类的方法的扩充,有些类似于类的继承,但是和继承还是不一样的.下面我 们通过一个例子还说明一个OC中的Category的不同. 首先是.h文件,一般的命 ...

  4. OC中category(分类)中添加属性

    OC中category(分类)中添加属性 因为OC中无法添加成员变量并且添加的属性不会被保存,所以需要重写get和set方法来实现属性的保存. //setter //self表示属性拥有者是当前类, ...

  5. 面试总结(CSS 的盒模型?、CSS 中选择器的优先级以及 CSS 权重如何计算?、CSS 中哪些属性可继承,哪些不可以?、CSS 单位中 px、em 和 rem 的区别?、rem 适配....)

    CSS 的盒模型?         盒子模型(Box Modle)可以用来对元素进行布局,包括内边距,边框,外边距,和实际 内容这几个部分                 第一种是 W3C 标准的盒子 ...

  6. Swift的数组与OC中数组的区别

    相同的值可以多次出现在一个数组的不同位置: Swift中的数组,数据值在被存储进入到某个数组之前类型必须明确,可以显示的类型标注或者类型推断.而且,Swift中的数组不必是对象类型. OC中的NSAr ...

  7. OC中常见面试题汇整篇

    当页面跳转的时候,如何实现导航条和页面同时出现?因为他两个经常出现不同步的现象? 如何将tablview强制转换成UIScrollow? 当一个界面在6s上正好可以完全呈现,那在4s上面你是如何处理的 ...

  8. java和oc_Java和OC中的数据容器和数组

    Java和OC中的数据容器和数组 在文章List/Set/Map的区别里我们讨论了Java的数据容器,由于其面向接口的编程特性,让我回忆了一下OC里面的「NSArray」和「NSMutableArra ...

  9. OC中类别、扩展、协议与托付

    类别(category)--通过使用类别,我们能够动态地为现有的类加入新方法.并且能够将类定义模块化地分不到多个相关文件里.通常仅仅在类别中定义方法. 类别,接口部分的定义,通常该文件命名为已有&qu ...

最新文章

  1. Android项目驱动式开发教程 第2版,《Android项目驱动式开发教程》第一章开发入门.ppt...
  2. 我去字节跳动面试,“偷”回来的面试题,题真难...
  3. 【Spark深入学习 -14】Spark应用经验与程序调优
  4. 使用SpringMVC 的MultipartFile文件上传时参数获取的一个坑
  5. js之 foreach, map, every, some
  6. [转]软件测试演义——中高级系列(序)
  7. Win10+Ubuntu16.04/Ubuntu18.04双系统安装教程
  8. 关于springmvc配置validator的注意事项
  9. vue项目的导出功能
  10. LaTex关于数学公式的使用(5)--- 积分
  11. C# 发送邮件之QQ邮箱
  12. 自然语言处理之hmm(隐马尔可夫模型)
  13. 用python批量修改后缀名
  14. 【nn.Conv3d】三维卷积参数量与运算量
  15. yum源服务器本地配置
  16. hdu 2475 box LCT
  17. 树和二叉树的知识点考前总结
  18. 銀織の雷使い(プレメア) / 银雷(异时层机娘)
  19. 2022 年度“ 楚怡杯” 中职网络空间安全湖南省职业院校技能竞赛
  20. 浅谈RFID资产管理-RFID资产可视化管理系统

热门文章

  1. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(二)转载自码农网
  2. 2015年9月百度前端在线笔试
  3. xp下msn8.5无法安装的解决办法
  4. 《spring 2.0技术手册》入门不错!
  5. jquery ajax示例
  6. UI第九节——UIProgressView
  7. div中的内容水平垂直居中
  8. 塔式、机架式、刀片式服务器的区别和特点
  9. 【转】解决IIS 用localhost需要用户名密码!
  10. 学习J2ME编程需要掌握的七种技术