是的,你是对的。删除接口后,代码仍将编译。那么为什么要添加它们呢?
好吧,您的IAddition 和ISubtraction 示例并不能很好地说明我的观点。既然学习编程最好的方式就是看别人是怎么写代码的,我就以System.IComparable<T>接口为例。它是.NET框架提供的接口。
我们之所以使用接口,是为了实现多态。接口就像类必须遵守的协议。如果一个类实现了一个接口,则保证该类可以做接口指定的事情。这一切听起来很混乱,所以让我们看一下IComparable<T> 接口。为了让事情更简单,让我们把它改成IComparable<int>
IComparable<int>有这个方法:
int CompareTo(int other);
这基本上意味着
所有实现IComparable<int>的东西都有能力与整数进行比较。我们可以调用它的CompareTo方法来判断它是大于、等于还是小于任何int。
由于实现IComparable<int> 的所有东西都必须具有CompareTo 方法,因此可以保证您调用CompareTo 的对象可以与int 进行比较。
那么这有什么用呢?
当您对数组进行排序时,与其他事物进行比较的能力很有用。 Array.Sort 方法使用IComparable<T> 接口。以下是Sort 方法的工作原理(高度简化):
它首先检查数组的元素是否可以比较,检查它们是否实现IComparable<T>。如果有,请致电CompareTo 进行比较!为什么可以这么肯定有一个方法叫CompareTo?因为对象都实现了IComparable<T>,这就保证了CompareTo方法!比较之后,Sort 可以判断出哪个元素在先和最后。
您知道不同的事物需要进行不同的比较吗?整数和doubles 可以通过将一个相减并检查结果是正数还是负数来进行比较。但是字符串是按字母顺序比较的。如果没有IComparable<T> 接口,那么对于字符串将有一个不同的Sort 方法,对于int 有一个Sort 方法,对于所有可以比较的类型都有一个Sort 方法。更糟糕的是,如果客户端代码创建了可以比较的东西,客户端代码需要编写自己的Sort 方法!不要忘记,还有很多其他方法可以利用比较的能力。是否所有那些方法都需要为每种类型提供不同的版本?
这就是接口如此重要的原因。有了它们,只需要一个Sort 方法,因为多态会处理其余的事情。
让我总结一下接口的优点:
- 它提供了灵活性(整数和字符串都可以与整数和字符串进行比较,但方式不同)
- 它减少了代码(您不需要编写额外的
Sort 方法!)
- 它确保安全(如果你忘记实现一个方法,编译器会告诉你!)
我们假设IComparable<T>不存在,而string和int等类型可以比较为自己的CompareTo方法。 Sort 方法看起来像这样
public static void Sort(int[] arr) {
// note that I'm using bubble sort here. A real sort method wouldn't use this coz it's slow.
// source: http://stackoverflow.com/questions/14768010/simple-bubble-sort-c-sharp
int temp = 0;
for (int write = 0; write < arr.Length; write++) {
for (int sort = 0; sort < arr.Length - 1; sort++) {
if (arr[sort].CompareTo(arr[sort + 1]) > 0) {
temp = arr[sort + 1];
arr[sort + 1] = arr[sort];
arr[sort] = temp;
}
}
}
}
public static void Sort(string[] arr) {
string temp = 0;
for (int write = 0; write < arr.Length; write++) {
for (int sort = 0; sort < arr.Length - 1; sort++) {
if (arr[sort].CompareTo(arr[sort + 1]) > 0) {
temp = arr[sort + 1];
arr[sort + 1] = arr[sort];
arr[sort] = temp;
}
}
}
}
您可能会争辩说,一个采用object[] 检查每个元素类型的Sort 方法也可以工作。是的,但这与多个Sort 方法存在相同的问题。如果创建了新的可比较类,您仍然需要添加另一个排序方法或另一个检查。
如果你有IComparable<T>接口,问题就全部结束了!
public static void Sort<T>(T[] arr) where T : IComparable<T> {
T temp;
for (int write = 0; write < arr.Length; write++) {
for (int sort = 0; sort < arr.Length - 1; sort++) {
if (arr[sort].CompareTo(arr[sort + 1]) > 0) {
temp = arr[sort + 1];
arr[sort + 1] = arr[sort];
arr[sort] = temp;
}
}
}
}
由于类型约束表明T 必须实现IComparable<T>,因此可以毫无问题地对数组中的每个对象调用CompareTo!
现在,如果您想添加另一个可比较的类,您需要做的就是实现接口。而如果接口不存在,则必须编写一个CompareTo 方法和一个Sort 方法!