我是一名长期的 OO 程序员和函数式编程新手。从我的小曝光来看,代数数据类型对我来说只是一种特殊的继承情况,你只有一个层次结构,父类(super class)不能扩展到模块之外。
所以我的(可能是愚蠢的)问题是:如果 ADT 就是这样,继承的一个特殊情况(同样,这个假设可能是错误的;在这种情况下请纠正我),那么为什么继承会受到所有批评而 ADT 会得到所有的赞美?
谢谢。
最佳答案
我认为 ADT 是继承的补充。它们都允许您创建可扩展的代码,但可扩展性的工作方式不同:
- ADT 可以轻松添加新功能以处理现有类型
- 您可以轻松添加与 ADT 一起使用的新功能,它有一组固定的案例
- 另一方面,添加新案例需要修改所有功能
- 继承可以在您拥有固定功能时轻松添加新类型
- 您可以轻松创建继承类并实现一组固定的虚函数
- 另一方面,添加新的虚函数需要修改所有继承的类
面向对象世界和函数世界都开发了自己的方法来允许其他类型的可扩展性。在 Haskell 中,您可以使用类型类,在 ML/OCaml 中,人们会使用函数字典或 (?) 仿函数来获得 inhertiance-style 可扩展性。另一方面,在 OOP 中,人们使用访问者模式,这本质上是一种获得类似 ADT 的方式。
通常的编程模式在 OOP 和 FP 中是不同的,因此当您使用函数式语言进行编程时,您正在以更频繁地需要 函数式 可扩展性的方式编写代码(在 OOP 中也是如此)。在实践中,我认为拥有一种允许您根据要解决的问题同时使用这两种样式的语言非常棒。
关于java - 为什么 ADT 好而继承不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3271974/