V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
qW7bo2FbzbC0
V2EX  ›  问与答

单继承编程语言如何优雅的实现鸭子类型的属性?

  •  
  •   qW7bo2FbzbC0 · 2020-05-20 15:42:56 +08:00 · 1372 次点击
    这是一个创建于 1659 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原本在 python 或者 c++这种多继承语言中可以实现如下继承逻辑

    class TableFootPrint {
        create_at datetime
       update_at datetime
    
    }
    
    class TableHistory {
       delete_at datetime
       delete_by datetime
    }
    
    class TableX inherit TableFootPrint {
      id int
      name string
      .....
    }
    
    class TableXHistory inherit TableX,TableHistory {
    
    }
    
    class SimpleTableY  {
      id int
      name string
      .....
    }
    
    class SimpleTableYHistory inherit TableHistory  {
      id int
      name string
      .....
    }
    

    但是如果单继承的话,似乎要重复手打 TableHistory 的属性

    如果在 ES6 中,可以用展开符...baseObj来实现重复属性的引入

    但 C# 中没有展开符语法糖。。。。。。不知道 JAVA 有没有,但估计也没有。

    问下单继承中如何实现上述逻辑?

    14 条回复    2020-05-20 17:49:09 +08:00
    qW7bo2FbzbC0
        1
    qW7bo2FbzbC0  
    OP
       2020-05-20 15:55:25 +08:00
    多继承:
    M = A +B ,
    N = A + C + D
    O = B + C
    .......

    单继承:
    做一次完整的排列组合,然后再去继承
    qW7bo2FbzbC0
        2
    qW7bo2FbzbC0  
    OP
       2020-05-20 15:55:41 +08:00
    不知道这样的理解对不对
    wutiantong
        3
    wutiantong  
       2020-05-20 16:23:22 +08:00
    你这哪有鸭子类型?
    qW7bo2FbzbC0
        4
    qW7bo2FbzbC0  
    OP
       2020-05-20 16:48:16 +08:00
    @wutiantong 抱歉,我描述的不够清晰,不局限于鸭子类型

    假设下面的属性是最小必须集合

    鱼 继承 水生动物的属性
    牛 继承 陆生动物的属性
    青蛙 同时 继承水生动物和动物属性

    工科学生 继承 工科课程
    医学学生 继承 医学课程
    工科医学双学士 继承 医学课程 工科课程

    如果是多继承 那么一个青蛙既是水生同时又陆生,一个学生同时在学习医学和功课课程

    如果是单继承,那么一个青蛙必须先是水生或者陆生,然后是两栖,一个学生是先学习完医学或者工科,然后在学习另外一门才是双学士

    单继承想实现这种理论存在的多继承关系,必须先构造 A 然构造 A + (拆分 B), 然后才能真正的实现现实世界中多继承吗?
    wutiantong
        5
    wutiantong  
       2020-05-20 17:02:49 +08:00
    @hjahgdthab750

    你有点缺乏工程实践。

    oop 并非要去模拟现实,继承不可滥用

    继承要解决的主要问题是代码复用,核心在于多态

    注意,我们希望复用的东西是 functions 而非 attributes

    因此,你在这里讨论的事情其实没什么意义。
    wutiantong
        6
    wutiantong  
       2020-05-20 17:08:24 +08:00
    Java 的单继承被证明有效地降低了多继承导致的复杂和混乱,而 Protocol 在很大程度上可以近似于多继承的效果。

    发展到近些年甚至出现了“面向接口编程”的理念,这些事情你知道么?
    wutiantong
        7
    wutiantong  
       2020-05-20 17:15:33 +08:00
    继承之所以被滥用,可能是因为很多人没有意识到“组合”通常是更合适的做法。
    qW7bo2FbzbC0
        8
    qW7bo2FbzbC0  
    OP
       2020-05-20 17:32:57 +08:00
    @wutiantong 那么在 JAVA 中如何复用 attributes 或者 property 呢?
    WenhaoWu
        9
    WenhaoWu  
       2020-05-20 17:34:27 +08:00 via iPhone
    关键词是 composition over inheritance,楼主可以了解下
    wutiantong
        10
    wutiantong  
       2020-05-20 17:35:56 +08:00
    @hjahgdthab750 就如刚才说过的,组合( composition )通常是更好的做法。
    qW7bo2FbzbC0
        11
    qW7bo2FbzbC0  
    OP
       2020-05-20 17:37:27 +08:00
    @wutiantong 把复用的属性打包成一个个最小的纯净 class,然后用的时候用多继承方式搭积木一样拼在一起,这种思路不对吗
    qW7bo2FbzbC0
        12
    qW7bo2FbzbC0  
    OP
       2020-05-20 17:38:14 +08:00
    @wutiantong @WenhaoWu 谢谢,我去看一下
    qW7bo2FbzbC0
        13
    qW7bo2FbzbC0  
    OP
       2020-05-20 17:44:29 +08:00
    看了下 composition,这种还是有点别扭,不如多继承那么自然,用多继承的时候会需要考虑同名属性或者方法的覆盖关系。但是如果刻意的避免重复属性或者方法,或者定义重复属性的覆盖关系,是不是就可以避免多重继承带来的问题了?
    wutiantong
        14
    wutiantong  
       2020-05-20 17:49:09 +08:00
    @hjahgdthab750 你永远不需要去复用 attributes,真正需要复用的是“行为(functions)”。对象的“行为”才是 oop 中的焦点。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5785 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 93ms · UTC 01:43 · PVG 09:43 · LAX 17:43 · JFK 20:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.