首页 > 代码库 > 9.4.2 实现接口和类型转换
9.4.2 实现接口和类型转换
9.4.2 实现接口和类型转换
我们已经讨论过在 F# 中如何声明接口,如何使用对象表达式,创建实现接口的值。这是一个非常轻量级的解决方案,类似于 lambda 函数。正如 lambda 语法,对于创建函数来说,并不总是合适的选择一样,有时,在命名类中实现接口,是有道理的。
我们将继续使用在本章前面的示例,来看一下用 C# 和 F# 实现接口,我们回顾一下两种语言中的接口声明:
// C# interface declaration
interface IClientTest {
bool Check(Client client);
void Report(Client client);
}
// F# Interface declaration
type ClientTest =
abstract Check : Client –>bool
abstract Report : Client –> unit
接口有两个方法:一个检查客户,另一个把报告输出到屏幕。假设我们要实现接口,使用几个属性计算系数。早些时候,我们使用对象表达式创建了类似的检查,但是,当代码变得更加复杂时,把它移动到单独的类声明,或成为单独的源文件,会更好一些。
清单 9.17 显示了用 C# 实现的检查客户的收入和工作年限,使用了权重和阈值,所有这些都在构造函数中指定。类使用显式接口实现(explicit interface implementation),稍有点不寻常,但我们要等到讨论用 F#实现时,才会知道为什么。
清单 9.17 使用显式接口实现的客户检查 (C#)
class CoefficientTest : IClientTest { <-- 实现 IClientTest
readonly double incomeCoeff,yearsCoeff, minValue;
public CoefficientTest(double ic, doubleyc, double min) { | 把参数值保存在
this.incomeCoeff = ic; | 私有字段中
this.yearsCoeff = yc; |
this.minValue = http://www.mamicode.com/min; |
}
public void PrintInfo() {
Console.WriteLine("income * {0}+ years * {1} >= {2}",
incomeCoeff, yearsCoeff,minValue);
}
bool IClientTest.Check(Client client){ |
return client.Income * incomeCoeff+ | [1]
client.YearsInJob *yearsCoeff < min; | 实现接口方法
} |
void IClientTest.Report(Client client){ |
Console.Write("Coeffficient {1}less than {0} ", minValue, |
client.Income *incomeCoeff + cl.YearsInJob * yearsCoeff); |
} |
}
要在 C# 中使用明确的语法实现接口成员,我们在写方法时[1],要包括接口的名字,并去掉访问修饰符。这只是一个微小的变化,而更重要的区别是如何使用类。接口中的方法(在这里,是Test 和 Report),在使用类时,不能直接访问;为了调用它们,首先要把类转换成接口类型。我们看一个例子:
var test = new CoefficientTest(0.001, 5.0,50.0);
test.PrintInfo();
var cltest = (IClientTest)test;
if (cltest.Check(john))cltest.Report(john);
我们不能简单地写成 test.Check(john),因为 Check 不是直接作为类的公共方法,只能作为接口的成员使用,因此,可以使用 cltest 值来访问,它的类型为 IClientTest。我们在代码中用明确的类型转换,和 var 关键字,因为这能帮助我们理解,在 F# 中接口实现是如何工作的。另一种选择是把变量类型声明成 IClientTest,然后,把值 test 赋给它,因为C# 编译器将它隐式转换为接口类型。
除了使用显式接口实现以外,类是完全不值一提;我们将使用它来对比 F# 代码。说到这......
9.4.2 实现接口和类型转换