在关于接口编程的 SO 问题中,评论者说 -
这个问题的大多数答案都有一个普遍的误解,即“编程到接口”意味着使用接口语言结构;这是完全错误的!这是我看到的第一个正确说明“编程到接口”的答案意味着:不要将您的“客户端代码”不必要地绑定到具体/特定的子类实现,因为如果您以后决定使用不同的实现来更改它,您需要做更多的工作来撤消所有不必要的绑定。即程序到/绑定到没有实现细节的东西。例如抽象基类。;)
可以请一些人扩展这一点,最好是与c#有关。
在关于接口编程的 SO 问题中,评论者说 -
这个问题的大多数答案都有一个普遍的误解,即“编程到接口”意味着使用接口语言结构;这是完全错误的!这是我看到的第一个正确说明“编程到接口”的答案意味着:不要将您的“客户端代码”不必要地绑定到具体/特定的子类实现,因为如果您以后决定使用不同的实现来更改它,您需要做更多的工作来撤消所有不必要的绑定。即程序到/绑定到没有实现细节的东西。例如抽象基类。;)
可以请一些人扩展这一点,最好是与c#有关。
我的解释是,答案只是将“接口”的概念扩展为意味着绑定到任何一组属性和方法,无论是“纯”接口(即interface
C# 中的接口)还是绑定到特定的实现。答案的要点是,您可以将一个类本身视为“接口”,因此您应该对您的使用所需的最低基类进行编程(通用List
合同与更具体的ArrayList
合同就是该示例)。
System.IO
您在绑定到抽象TextReader
类与(不存在的)ITextReader
接口的类中经常看到这一点。
例子:
如果您有一种方法可以让“动物”在您的手机游戏中运行,您可以定义一个
IAnimal
界面,并为每个动物定义自己的运行机制。
public interface IAnimal {
Run();
}
public Dog : IAnimal{
public void Run() {
//DOG RUN CHINEMATICS
}
}
public Elephant: IAnimal{
public void Run() {
//ELEPHANT RUN CHINEMATICS
}
}
因此,您将具体实现隐藏在抽象IAnimal
背后(通常称为接口契约)。
因此,在您的物理引擎运行期间,您可以简单地定义一种方法:
public void RunAnimal(IAnimal animal) {
animal.Run();
}
并称之为:
RunAnimal(new Dog()); //WILL CALL DOG CONCRETE METHOD
RunAnimal(new Elephant()); //WILL CALL ELEPHANT CONCRETE METHOD
因此,对于RunAnimal
方法,动物的具体实施细节隐藏在IAnimal
“墙”后面。
编辑
因此,对于“为什么对接口进行编程而不是简单地使用接口构造”这个问题的答案?是:
您可以使用它来构建或基于架构的interface
工具。只需使用或with即可实现相同的目的。所以“接口编程”:是通过记住向消费者代码隐藏具体实现细节(尽可能多地)进行编程,以确保程序的最大可维护性、灵活性和可扩展性。使用, , , 随便你。interface
contract
abstract base class
simple base class
virtual methods
interface
abstract class
base class
使用接口,您只有方法的签名
使用抽象类,您可以设置子类的通用行为,因此编写通用代码
对于 C# 来说,多重继承是不可能的,所以
你可以实现多个接口而不是继承多个抽象类
当您创建分布式组件(例如 WCF Remoting 等)时,您需要实现接口以便与您的客户端进行通信。
您可以使用接口来标记类