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

时间:2018-07-30 23:02:28

标签: oop inheritance f# functional-programming

面向对象的编程范例使用继承对遵循通用化-专业化关系的实体之间的关系进行建模。此处,基类用于封装一组实体的公共(通用)属性和行为,而派生类通过添加其他属性和/或添加/修改现有行为来扩展基类。

作为函数式编程的新手,我需要使用F#等函数式语言对这种关系进行建模的指导。

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

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

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

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

,然后使用 Tutorials 的集合并调用 learn 来观察多态行为。

1 个答案:

答案 0 :(得分:6)

在功能设计中,您对事物的思考有所不同,因此这些思想将无法完美地映射。通常,功能设计更多地关注表示您正在使用的实体的数据类型。在您的情况下,您可以使用专有的联合定义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风格的可扩展性”,则可以轻松使用接口。