Oop 函数式编程中如何建立继承关系模型
面向对象编程范式使用继承来建模遵循泛化-专门化关系的实体之间的关系。这里,基类用于封装一组实体的公共(通用)属性和行为,派生类通过添加其他属性和/或添加/修改现有行为来扩展基类 作为一名函数式编程新手,我需要在函数式语言(如F#)中对此类关系建模的指导 e、 g.对以下简单情况建模的最佳方法是什么:Oop 函数式编程中如何建立继承关系模型,oop,inheritance,f#,functional-programming,Oop,Inheritance,F#,Functional Programming,面向对象编程范式使用继承来建模遵循泛化-专门化关系的实体之间的关系。这里,基类用于封装一组实体的公共(通用)属性和行为,派生类通过添加其他属性和/或添加/修改现有行为来扩展基类 作为一名函数式编程新手,我需要在函数式语言(如F#)中对此类关系建模的指导 e、 g.对以下简单情况建模的最佳方法是什么: abstract class Tutorial { private String topic; abstract public void learn(); } class VideoTu
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风格的可扩展性”,您可以轻松地使用接口。谢谢,现在我理解了思维过程中的变化。但是使用这种方法,不意味着如果我以后想添加AudioTutorial,我需要修改这两种类型以及学习函数吗。请告诉我,OO方法是否更适合这种情况。@S.Singh-是的,这意味着如果您想添加
AudioTutorial
,您需要修改TutorialKind
类型和learn
函数。但是,如果您想添加一个函数来完成教程中的其他功能,您只需要编写一个函数(而不是修改所有类,这是必须在OO中完成的)。所以,视角的改变是双向的。。。在F#中,函数式样式是一种很好的默认样式,但是如果您正在使用插件构建一些确实需要OO类型的可扩展性的东西,那么您可以使用OO和接口。是的,要添加新类型的教程,您确实需要修改该类型以及与之相关的所有函数。另一方面,在C#中,要添加新操作,确实需要修改每个现有类型。一般认为,编程语言很难同时具备这两种能力。这个问题是如此常见的一个地方,它有自己的名字-的。C只解决了问题的一半,F同时解决了两个问题,但不是同时解决。@FyodorSoikin-你能解释一下“F同时解决了两个问题,但不是同时解决”吗。它是否指的是语言的混合性质,我们可以用函数方式或面向对象方式对数据建模……是的。在F#中,您可以使用类和接口对域进行建模,也可以使用有区别的联合进行建模。前者提供了添加新类型的简单方法,后者提供了添加新操作的简单方法。但你不能同时做这两件事。