OC中protocol、category和继承的区别

OC中protocol、category和继承的区别框架

利用继承,多态是一个很好的保持“对扩展开放、对更改封闭”(OCP)的办法,也是最多见的一种方法。Objective C还支持另外两种语法来支持OCP:Protocol和Category。Protocol只能定义一套接口,而不能提供实现,变相的也是一种Abstract class的实现方式(oc 语法上自己不支持抽象基类)。Category能够为类提供额外的接口和实现。那么到底三者(继承, Protocol,Category)在使用上到底有什么本质的区别呢?在我看来,protocol的做用是为一些列类仅仅提供一套公用的接口,而彻底没 有办法也没可能去提供具体的一些实现状况;category则是为一个已有的类提供一些额外的接口和具体实现;而继承则基于二者之间,既能够想 protocol同样提供只是纯粹提供接口,也能够像Category同样提供完整的实现,并且继承还能对类之后的功能进行改写,因此说继承的力量是最强 大的。那么具体在使用的时候各自都适合什么样的状况呢?spa

        .        Protocol是定义行为而无论谁去怎么实现,这是一种比较洒脱和不负责的状况,就好像在外包项目中的客户同样,他只是他须要什么什么东西,具体实现他不会也不能给出同样。delegate datasource这样的就用protocol实现比较好继承

        .        Category是对一个功能完备的类的一种补充,就像是一个东西的主要基本功能都完成了,能够用category为这个类添加不一样的组件,使得 这个类可以适应不一样状况的需求(可是这些不一样需求最核心的需求要一致)。找个就像你已经有了一辆可以开动的汽车同样,咱们能够用Category为你的汽 车添加各类以前没有的功能,最后让这辆汽车变成超级跑车同样。接口

        .        当某个类很是大的时候,Category能够按不一样的功能将类的实现分在不一样的模块中实现。开发

        .        继承则是均可以完成上面的工做,可是继承有很大的代价问题,一是经过继承来进行扩展是一种耦合很高的行为,对父类能够说是彻底依赖;二是继承因为 对父类依赖,因此开发代价相对大,要求对父类的工做流程相对熟悉;三是继承体系若是太复杂会致使整个系统混乱,难以维护。因此在可以用上面两种方法完成扩 展的时候,就千万不要使用继承。什么状况才是无可奈何要使用继承呢?那就是若是你既想提供一系列接口的定义,同时又想提供一些可是又不能提供所有的实现的 时候,这种状况就要使用继承了。因此这么看来继承是对上面两种功能的一个黏合剂。编译器

关于category的另一些看法:工作流

        .        虽然category能够访问类的实例变量,去不能建立新的实例变量,若是要创新的实例变量,请使用继承;it

        .        在category中,不提倡对原有方法进行重载。缘由很是简单,在category中进行重载,没法对原方法进行访问,而继承中可使用super。若是真的须要对原方法进行重载,请考虑继承,好比我要定义一个继承自UIViewController的类,就不能用Category,由于,这我定义的这个类中,我要实现UIViewController中的viewDidLoad、init等方法,用了category后父UIViewController中的这些方法将没法被调用;编译

        .        一个类能够定义多个category,可是若是不一样category中存在相同方法,编译器没法决定使用哪一个category;class

        .        在定义category时,咱们能够仅仅给出方法定义,而不须要给出具体的实现。这在程序增量开发时是很是有帮助的;

        .        category是能够被继承的。在某个父类中定义了category,那么他全部的子类都具备该category;

        .        在须要为某个类建立私有成员方法时,也用category的方式来实现。

Category不能彻底代替子类,有如下几个最大的缺点:

        .        当在Category中覆盖一个继承的方法,在Category中的方法能够经过向super类发送一个消息来调用被继承的方法。可是,若是Category中覆盖的那个方法已经在这个类的其它Category定义过了,则以前定义的方法将没有机会被程序调用

        .        在Category中没法肯定其可以可靠的覆盖某个方法,而这个方法已经在其它的Category中定义过。这个问题在使用Cocoa框架时尤为 突出。当你想覆盖某个框架已经定义好的方法时,该方法已经在其它Category中实现,这样就没法肯定哪一个定义和实现会被最早使用,带来很大的不肯定 性。

        .        若是你从新覆盖定义了一些方法,每每会致使这个方法在整个框架中实现发生了变化。举例来讲,若是你增长了NSObject中 windowWillClose:的实现,这会致使全部的窗口调用那个新实现的方法,从而改变全部NSWindows实例的行为。这会带来不少不肯定性, 并颇有可能致使程序的崩溃。

相关文章
相关标签/搜索