接口的原因确实让我难以理解。据我了解,这是一种解决 C# 中不存在的不存在的多重继承的工作(或者我被告知)。
我所看到的是,您预定义了一些成员和函数,然后必须再次在类中重新定义它们。从而使接口变得多余。感觉就像句法——好吧,对我来说是垃圾(请没有冒犯的意思。垃圾就像无用的东西一样)。
在下面给出的示例中,该示例取自堆栈溢出时的不同 C# 接口线程,我将只创建一个名为 Pizza 的基类,而不是一个接口。
简单的例子(取自不同的堆栈溢出贡献)
public interface IPizza { public void Order(); } public class PepperoniPizza : IPizza { public void Order() { //Order Pepperoni pizza } } public class HawaiiPizza : IPizza { public void Order() { //Order HawaiiPizza } }
关键是接口代表一个 合约 。任何实现类都必须具有的一组公共方法。从技术上讲,接口只控制语法,即存在哪些方法、它们得到什么参数以及返回什么。通常它们也封装语义,尽管这只是通过文档。
然后,您可以拥有接口的不同实现并随意交换它们。在您的示例中,由于每个比萨实例都是一个IPizza,因此您可以IPizza在处理未知比萨类型实例的任何地方使用。任何类型继承自的实例IPizza都保证是可排序的,因为它有一个Order()方法。
IPizza
Order()
Python 不是静态类型的,因此类型会在运行时保留和查找。Order()因此,您可以尝试在任何对象上调用方法。只要对象有这样的方法,运行时就会很高兴,如果没有,可能只是耸耸肩说禄。在 C# 中并非如此。编译器负责进行正确的调用,如果它只是有一些随机object的,编译器还不知道运行时的实例是否具有该方法。从编译器的角度来看,它是无效的,因为它无法验证它。(你可以用反射或dynamic关键字来做这样的事情,但我猜现在这有点远了。)
object
dynamic
另请注意,通常意义上的接口不一定必须是 C# interface,它也可以是抽象类,甚至是普通类(如果所有子类都需要共享一些通用代码,这可以派上用场——在大多数情况下)但是,情况interface就足够了)。
interface