C#hack:接口和抽象类之间的低级差异

C#hack:接口和抽象类之间的低级差异,c#,oop,inheritance,interface,C#,Oop,Inheritance,Interface,这是一个关于C#基础的哲学问题:我想知道完全抽象的类可以模拟多接近一个接口。假设我们有以下接口: public interface INativeInterface { void PerformAction(); String Property { get; set; } } 以及以下抽象类: public abstract class ISimulatedInterface { public abstract void PerformAction(); pub

这是一个关于C#基础的哲学问题:我想知道完全抽象的类可以模拟多接近一个接口。假设我们有以下接口:

public interface INativeInterface
{
    void PerformAction();
    String Property { get; set; }
}
以及以下抽象类:

public abstract class ISimulatedInterface
{
    public abstract void PerformAction();
    public abstract String Property { get; set; }
}
他们有很多共同点,不是吗?我所知道的区别是:

  • 多重继承不适用于抽象类
  • 显式实现不适用于抽象类
可以通过使用反射或类似的方法跳过这些限制吗

我意识到接口和抽象类在根目录中是不同的:接口声明了一个条件“可以像”,抽象类-“是一种”,但即使如此,这看起来也非常接近,因此必须讨论这些实体之间的低级差异。这个问题听起来甚至像是“在C++中如何创建接口”

可以通过使用反射或类似的方法跳过这些限制吗

不是。抽象类和接口在公共语言运行时级别是不同的概念。因此,在C#中这两种情况都不可能发生,因为最终会受到CLR边界的限制

我想知道一个完全抽象的类可以模拟多接近一个接口

它是可行的,但需要底层执行环境(无论是物理环境还是管理环境)的支持(或“允许”)


在过去,我设计了一种完全用抽象类代替接口的语言。是的,它确实支持这种“接口”的多重继承。然而,实现特性可能不值得付出努力。主要的“低级差异”是继承的抽象类的内部嵌入实例必须保留在实现类的实例中,并且必须维护一系列
这个
指针。不用说,这是一次愉快的经历:-)

对我来说,这实际上可以归结为他们的能力。接口永远不会为其任何操作提供实现;它只承诺任何使用它的人都必须提供一些东西。抽象类可以为其任何操作提供实现,这些操作可以由其子类自行重写。不,你永远无法通过反射来覆盖这些限制,因为它们是语言本身的核心

至于使用抽象类代替接口,它再次归结为您需要完成什么。如果需要提供一些基本实现,则必须使用抽象类——否则,请使用接口


您已经提到的其他一些差异。您可以在C#中实现多个接口,但您只能从单个类(抽象类或其他类)派生。

这可能是OOPS哲学背景下的热门话题。正如我们所知,它没有什么技术区别,就像接口没有构造函数一样,继承类必须实现所有的方法等,但我喜欢用真实场景来讨论它。实际上,我认为接口是对象与其使用者之间的契约,但抽象类不是契约,即使两者都可以用来实现“liskov替换原则”。我想列举现实生活中的两种情况

1.)想象一个绘图应用程序,它可能包含形状、矩形、正方形等。在这里,形状可以是抽象类或接口类型。但如果我需要确保应用程序中的每个对象在实例化时都必须有一个状态。我无法通过接口实现此功能,因此接口无法保持对象的状态

2.)如果我的形状共享公共值(静态值),我无法使用接口实现这一点,所以我认为抽象类可以同时保持状态和行为


但考虑到界面,这是一个关于行为的协议,看一个真实的例子,动物和鸟类,这两个物体都有一些相似的行为,但我们不能说它们有共同的属性,鸟类和动物都可以行走、哭泣、进食,这些行为的执行是完全不同的。在我们的编程界面中,在您只需要协议而不需要任何状态的情况下,它是一个理想的候选者。好的方面是消费者对象可以替换满足该协议的任何其他对象,di是一个最好的例子。

因此,如果我理解您的问题,您有两个相关的问题

第一个问题是“抽象类和接口之间的区别是什么”;第二个问题是,“在C#中,我可以通过使没有具体方法的抽象类像接口一样工作来绕过这些差异吗?”

第一个问题在@Todd Schiller的链接中得到了很好的回答

第二个问题更复杂

您可能会创建一个构建时任务,将没有具体实现的所有抽象类转换为接口。我从未尝试过——因为我认为这样做没有好处,还有很多很多缺点

最大的缺点是代码变得更难调试和维护。开发人员学习何时创建抽象类,何时创建接口;这是一个公认的习语。在代码库上工作的新开发人员需要学习很多新东西,而引入一种新的方式来思考接口和抽象类将使这个过程变得更加困难和漫长

在调试应用程序时,如果开发人员在源代码中看到一个抽象类,但在运行时代码中看到它实际上是一个接口,那么他们可能会感到困惑,并花时间试图找出发生这种情况的原因,而不是跟踪真正的错误


就我所知,没有明显的好处

可能重复@Toddscoller谢谢,这是关于一般的OO设计,这个问题是C#特定的注意,接口功能的一些限制实际上是limi