• 关于 继承、扩展和协议,深度好文


    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

  • 相关阅读:
    maven常用命令
    div标签width:auto无效
    将本地文件推送到码云
    Spring事件监听讲解
    常用js代码积累
    HTML中块级元素和行内元素的总结和区分
    box-shadow详解
    设置最小宽高的作用
    Java英语词汇表
    标识符
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7359751.html
Copyright © 2020-2023  润新知