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

2020-05-20 15:42:56 +08:00
 qW7bo2FbzbC0

原本在 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 有没有,但估计也没有。

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

1254 次点击
所在节点    问与答
14 条回复
qW7bo2FbzbC0
2020-05-20 15:55:25 +08:00
多继承:
M = A +B ,
N = A + C + D
O = B + C
.......

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

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

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

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

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

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

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

你有点缺乏工程实践。

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

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

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

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

发展到近些年甚至出现了“面向接口编程”的理念,这些事情你知道么?
wutiantong
2020-05-20 17:15:33 +08:00
继承之所以被滥用,可能是因为很多人没有意识到“组合”通常是更合适的做法。
qW7bo2FbzbC0
2020-05-20 17:32:57 +08:00
@wutiantong 那么在 JAVA 中如何复用 attributes 或者 property 呢?
WenhaoWu
2020-05-20 17:34:27 +08:00
关键词是 composition over inheritance,楼主可以了解下
wutiantong
2020-05-20 17:35:56 +08:00
@hjahgdthab750 就如刚才说过的,组合( composition )通常是更好的做法。
qW7bo2FbzbC0
2020-05-20 17:37:27 +08:00
@wutiantong 把复用的属性打包成一个个最小的纯净 class,然后用的时候用多继承方式搭积木一样拼在一起,这种思路不对吗
qW7bo2FbzbC0
2020-05-20 17:38:14 +08:00
@wutiantong @WenhaoWu 谢谢,我去看一下
qW7bo2FbzbC0
2020-05-20 17:44:29 +08:00
看了下 composition,这种还是有点别扭,不如多继承那么自然,用多继承的时候会需要考虑同名属性或者方法的覆盖关系。但是如果刻意的避免重复属性或者方法,或者定义重复属性的覆盖关系,是不是就可以避免多重继承带来的问题了?
wutiantong
2020-05-20 17:49:09 +08:00
@hjahgdthab750 你永远不需要去复用 attributes,真正需要复用的是“行为(functions)”。对象的“行为”才是 oop 中的焦点。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/673658

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX