首页 > 代码库 > 9.4.2.1 在 F# 中实现接口

9.4.2.1 在 F# 中实现接口

9.4.2.1 在 F# 中实现接口

 

清单 9.17 使用 C# 中的显式接口实现,因为,这是 F# 允许的唯一的接口实现的风格。在函数编程风格中,这通常足够了。如果确实需要直接公开类的功能,可以添加额外的、调用相同代码的成员。清单 9.18 显示了前面示例的 F# 版本。

 

清单 9.18 在类中实现接口 (F#)

type CoefficientTest(incomeCoeff,yearsCoeff, minValue) =  [1]

  let coeff(client) =                                      |

    float(client.Income) *incomeCoeff +                     |  [2]

    float(client.YearsInJob)* yearsCoeff                      |

  let report(client) =                                     |

    printfn"Coefficient %f less than %f" (coeff(client)) minValue  |

 

  member x.PrintInfo() = 

    printfn "income*%f+ years*%f > %f" 

               incomeCoeff yearsCoeff minValue

 

  interface ClientTest with                    |

    member x.Report(client)= report(client)      | [3]

    member x.Check(client) =coeff(client) < min  |

 

清单 9.18 使用的称为隐式类语法(implicit class syntax),这就是说,它直接在声明中指定构造函数的参数{1]。它有三个参数值,描述计算的系数。因为我们在成员的后面要引用这些参数,F# 编译器会自动把它们保存在类字段中。

接下来,我们定义了两个局部的辅助函数,使用标准的 let 绑定语法[2]。它们在类的外部是不可见的,只能给在代码中后面的其他成员使用。当实现接口时[3],我们使用 interface ... with 语法,把所有成员组织到一起,成为一个单独的接口,使用通常的成员来实现。如果我们还想把一些相同的功能公开作为公共方法,可以添加其他成员到类声明中,并调用本地的辅助函数。另外,我们可以在公共成员中实现功能,从接口实现中调用成员。

使用类非常像前面的 C# 版本,使用显式接口实现。在清单 9.19 中可以看到代码的 F# 版本。

 

清单 9.19 使用 F# 的类和接口 (F# Interactive)

> let test = new CoefficientTest(0.001,5.0, 50.0);;   <-- 创建类的接口

val test : CoefficientTest

 

> test.PrintInfo();;   <-- 使用类的方法

income*0.001000 + years*5.000000 >50.000000

 

> let cltest = (test :>ClientTest);;   [1]

val cltest : ClientTest

 

> if (cltest.Check(john)) thencltest.Report(john);;   <-- 使用接口的方法

Coefficient 45.000000 is less than50.000000.

 

清单 9.19 中的大多数应该是很简单的。唯一例外的代码是,把值转换成接口类型[1],因为,我们还没有讨论过类型转换(casts)。在 F# 中,有两种类型转换。在这里,编译器知道在编译时,转换会成功,因为,它知道这个类(CoefficientTest)实现了接口(ClientTest)。这称为向上转换(upcast)。在下一节,我们将详细讨论两种转换。

9.4.2.1 在 F# 中实现接口