华人澳洲中文论坛

热图推荐

    别再使用承继了,除非你想要交点税

    [复制链接]

    2022-10-7 12:45:38 45 0

    明天这一章的宗旨很简略,那就是——不要使用承继。
    它是致使耦合的一大首恶。
    使用承继的问题
    通常使用承继会有两种状况:
    不喜爱打字的顺序员,用承继来同享代码,好比有一系列类都承继同一个Base类。喜爱打字的顺序员,用承继来表现类之间的瓜葛,好比,猫属于植物。但这两种都存在问题。
    使用承继同享代码的问题
    由于子类和父类是耦合的,假如父类做了一定的修正,那末一切的子类都会随着遭殃。
    使用承继来表现类瓜葛的问题
    猫在作为一个生物来分类的时分,的确能够属于植物。
    然而,还有其余的分类规定,就算光从生物的畛域来分类,也有界门纲目科属种这些层级。好比,猫科、哺乳纲……
    这还没完,从其余标的目的也有许多分类的维度。好比,它也能够是宠物、能够是资产、能够是食品(植物维护协会别打我)……
    这就带来了一些潜伏的问题,就是咱们当初的承继形式,可能压根就无奈精确残缺地表白某个类。
    真的想要表白的话,可能会弄出一张扑朔迷离的网出来,而不是树。
    何况,当初大部份的编程言语都不反对多承继,好比Java。
    所以,间接从言语层面就把这条路堵死了。
    承继的代替计划
    既然承继有这么多问题,那末,咱们天然就需求一些代替计划了。
    接口
    在Java里,这个叫接口interface,其余言语里有别的叫法,好比协定、特质。
    间接用书中的例子吧。
    如果,咱们的车要同时具有定位和驾驶的功用,那末咱们能够定义两个接口:


    Image
    而后,用咱们的车来完成这两个接口:
    Image
    接口补足了不克不及多重承继的问题,并且,使得组合变得灵敏,车类和两个功用类,并无绑的那末死,这两个功用类其余类也能用。
    好比手机也能够具有定位的功用,那它也能够完成位置接口,而且车和手机能够放入同一个List外面,能够完成多态。


    image-20221004231741949拜托
    承继还有一个问题,就是它强迫让子类具有了得多功用。
    好比父类具有20个办法,我新建的之类只需求其中3个,然而此外17个办法也顺着承继给了之类,让咱们对类的行动失去管制。
    因而,咱们能够使用拜托的形式,相似于工具类,把某些任务拜托给其余专门干这件事的类。
    好比,想要让类耐久化,就调用耐久化类的功用:


    Image
    这还能够进一步优化,关于一个账户类来讲,它其实不需求知道如何耐久化本人,它只用关怀业务便可,咱们能够给账户类建一个包装类,这个包装类里完成了耐久化相干的功用:


    Image
    当初,账户和耐久化,算是完全解耦了,然而它的代价就是需求多些得多代码。
    有的时分,有一些对比通用的功用,简直一切类都需求用到,好比,查问功用,为每个类去写一个包装类,也太累了一点。
    因而就来到了咱们下一个模块。
    特性/混合
    这个特性在不同的言语中,也有不同的叫法,Java里没有。
    它的目的是,在不使用承继的条件下,对类或对象进行扩展。
    作者说,最佳把它当作与言语有关的计划,所以,更偏向于称它为混合Mixin。
    作者举的例子长这样,就是定义了公共查问类,而后让需求它的类混合在一同。


    Image
    而后, 其实书中并无明白地提到这个例子是用甚么言语写的,然而示例的代码中有用到了extends这个个别用于承继的症结字,让我一瞬间有些迷茫,多是前面的with改动了整句话的意思吧。
    所以,我有特地去搜一下extends……with的用法,我收到了一个叫scala的言语,有这个用法,并且也是用于trait(特性)的。所以,应该和作者的这个示例至关。
    而后,我贴一下,对于trait的一些阐明:


    image-20221005013545499










    这些阐明来着于这篇文章:
    http://www.cnblogs.com/qingyunzong/p/8870195.html
    从这些阐明能看出,这的确是一个挺纷歧样的货色的。只看前两条有点想Java的笼统类,然而加之后两条之后,就谁都不像了。再加之最初的两条,就更是谁都不像了。还有更首要的,即使是笼统类,也不克不及多承继,所以照样不克不及进行多混合。
    虽然,作者说了要把它当作一种没有言语有关的货色,然而假如言语自身不反对的话,好像也没有甚么太好的方法,只能说,当你有了这个认识之后,就会去关注它。
    好比,利用Java新加的default,能够完成了一个低配版的Mixin。
    Java中能够在接口中,使用default症结字来给办法定义默许的完成,这的确算是低配版吧。
    好比,最初一条就完成不了,假如完成的多个接口里有同一个办法的话,完成它们的类,必需得重写这个办法,而不是均可以调用。
    总之呢,就是能不使用承继就不要使用承继,由于要交“遗产税”,会带来许多连带的费事,我带来耦合,所以,使用代替计划来交换承继吧。

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    返回列表 本版积分规则

    :
    注册会员
    :
    论坛短信
    :
    未填写
    :
    未填写
    :
    未填写

    主题28

    帖子42

    积分185

    图文推荐