zoukankan      html  css  js  c++  java
  • 关于 继承、扩展和协议,深度好文

    OC中protocol、category和继承的差别曾经还是有点迷糊,面试的时候说的有点混乱。如今结合一些资料总结一下。

    利用继承,多态是一个非常好的保持“对扩展开放、对更改封闭”(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中,不提倡对原有方法进行重载。原因非常easy。在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实例的行为。

    这会带来非常多不确定性。 并不是常有可能导致程序的崩溃。

    http://bbs.itheima.com/thread-117162-1-1.html

  • 相关阅读:
    Photoshop 基础七 位图 矢量图 栅格化
    Photoshop 基础六 图层
    Warfare And Logistics UVALive
    Walk Through the Forest UVA
    Airport Express UVA
    Guess UVALive
    Play on Words UVA
    The Necklace UVA
    Food Delivery ZOJ
    Brackets Sequence POJ
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7359751.html
Copyright © 2011-2022 走看看