oop - 如何在函数式编程中建模继承关系

标签 oop inheritance f# functional-programming

面向对象的编程范式使用继承来建模遵循泛化-特化关系的实体之间的关系。在这里,基类用于封装一组实体的公共(public)(通用)属性和行为,派生类通过添加附加属性和/或添加/修改现有行为来扩展基类。

作为函数式编程的新手,我需要有关在 F# 等函数式语言中建模此类关系的指导。

例如模拟如下简单情况的最佳方法是什么:

abstract class Tutorial { 
  private String topic;
  abstract public void learn();
}

class VideoTutorial extends Tutorial {
  private float duration;
  public void learn () {
    System.out.println ("Watch Video");
  }
}

class PDFTutorial extends Tutorial {
  private int pageCount;
  public void learn () {
    System.out.println ("Read PDF");
  }
}

然后稍后使用一组教程并调用 learn 来观察多态行为。

最佳答案

在功能设计中,您对事物的看法有所不同,因此这些想法​​不会完美映射。通常,功能设计更侧重于表达您正在使用的实体的数据类型。在您的情况下,您可以定义 TutorialKind它是视频或 PDF,使用有区别的联合和 Tutorial然后将是包含一种类型及其主题的记录:

type TutorialKind = 
  | VideoTutorial of duration:float
  | PDFTutorial of pageCount:int

type Tutorial = 
  { Kind : TutorialKind
    Topic : string }

请注意,这仅保留有关教程的数据。任何功能都可以在与教程类型匹配的函数中实现:
let learn tutorial = 
  match tutorial.Kind with
  | VideoTutorial _ -> printfn "Watch video"
  | PDFTutorial _ -> printfn "Read PDF"

请注意,这可以在与 OO 版本不同的方向上进行扩展。在 OO 中,您可以轻松地添加新的子类;在这里您可以轻松添加新功能。在实践中,函数式人员通常对这种更改感到满意,但 F# 是一种混合语言,如果您需要“OO 风格的可扩展性”,您可以轻松使用接口(interface)。

关于oop - 如何在函数式编程中建模继承关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51603369/

相关文章:

oop - 帮助设计树结构 - 函数式和 OOP 之间的张力

oop - 依赖注入(inject)容器 - 工厂模式

python - 基本的 Python(ic) 继承问题

c++ - 尝试从基类访问 protected 构造函数时出现错误 C2248

.net - 列表、数组或其他什么?

c# - 继承需要存储子类特定数据的数组的最佳方法是什么?

javascript - js继承和原型(prototype)赋值

c++ - 如何声明两个不同的静态变量? (C++)

.net - 如何创建目标框架为 .NET Standard 2.0 的 F# 库?

visual-studio - FSharp 项目构建在 TeamCity 中的 MSBuild 中失败