我真的不明白接口存在的原因。据我所知,这是c#中不存在的多继承的一种工作(至少我是这么被告知的)。

我所看到的是,您预定义了一些成员和函数,然后必须在类中再次重新定义它们。从而使接口成为冗余。它只是感觉像句法……嗯,垃圾对我来说(请没有冒犯的意思。Junk是指无用的东西)。

在下面的例子中,我将创建一个名为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
    }
}

当前回答

接口也可以通过菊花链来创建另一个接口。这种实现多个接口的能力使开发人员可以在不改变当前类功能的情况下向类中添加功能(SOLID原则)

O = "类应该对扩展开放,对修改关闭"

其他回答

接口用于驱动一致性,以一种松散耦合的方式,这使得它不同于紧密耦合的抽象类。这就是为什么它通常也被定义为合同。实现接口的任何类都必须遵守接口定义的“规则/语法”,并且其中没有具体的元素。

我将给出一个下图所支持的例子。

Imagine in a factory there are 3 types of machines.A rectangle machine,a triangle machine and a polygon machine.Times are competitive and you want to streamline operator training.You just want to train them in one methodology of starting and stopping machines so you have a green start button and red stop button.So now across 3 different machines you have a consistent way of starting and stopping 3 different types of machines.Now imagine these machines are classes and the classes need to have start and stop methods,how you going to drive consistency across these classes which can be very different? Interface is the answer.

一个简单的例子来帮助你可视化,有人可能会问为什么不用抽象类呢?有了接口,对象不必直接相关或继承,你仍然可以在不同的类之间保持一致性。

public interface IMachine
{
    bool Start();
    bool Stop();
}

public class Car : IMachine
{
    public bool Start()
    {
        Console.WriteLine("Car started");
        return true;
    }

    public bool Stop()
    {
        Console.WriteLine("Car stopped");
        return false;
    }
}

public class Tank : IMachine
{
    public bool Start()
    {
        Console.WriteLine("Tank started");
        return true;
    }

    public bool Stop()
    {
        Console.WriteLine("Tank stopped");
        return false;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var car = new Car();
        car.Start();
        car.Stop();

        var tank = new Tank();
        tank.Start();
        tank.Stop();

    }
}

接口的主要目的是在您和实现该接口的任何其他类之间建立契约,使您的代码解耦并允许可扩展性。

我在这个页面上搜索了“合成”这个词,但一次也没看到。这个答案是对前面提到的答案的补充。

在面向对象项目中使用接口的一个绝对重要的原因是,它们允许你更倾向于组合而不是继承。通过实现接口,您可以将您的实现与应用于它们的各种算法解耦。

德里克·巴纳斯(Derek Banas)的“装饰图案”教程(有趣的是,它也以披萨为例)是一个有价值的插图:

https://www.youtube.com/watch?v=j40kRwSm4VE

什么?

接口基本上是一个契约,所有实现接口的类都应该遵循这个契约。它们看起来像一个类,但没有实现。

在c#中,接口名称的约定是由前缀“I”定义的,所以如果你想要一个名为shapes的接口,你可以将它声明为IShapes

为什么?

提高代码的可重用性

假设你想画圆,三角形。 你可以把它们组合在一起,称为形状,并有方法来绘制圆形和三角形 但有具体的实现将是一个坏主意,因为明天你可能会决定有2个形状矩形和正方形。现在,当您添加它们时,很可能会破坏代码的其他部分。

使用Interface,您可以将不同的实现与契约隔离开来


现场场景第一天

你被要求创建一个应用程序来绘制圆形和三角形

interface IShapes
{
   void DrawShape();
   
 }

class Circle : IShapes
{
    
    public void DrawShape()
    {
        Console.WriteLine("Implementation to Draw a Circle");
    }
}

Class Triangle: IShapes
{
     public void DrawShape()
    {
        Console.WriteLine("Implementation to draw a Triangle");
    }
}
static void Main()
{
     List <IShapes> shapes = new List<IShapes>();
        shapes.Add(new Circle());
        shapes.Add(new Triangle());

        foreach(var shape in shapes)
        {
            shape.DrawShape();
        }
}

现场场景第二天

如果你被要求添加Square和Rectangle,你所要做的就是在Square: IShapes类中创建它的实现,并在Main中添加到列表形状。添加(新广场());

这些都是很好的例子。

另外,在switch语句的情况下,您不再需要在每次希望里约热内卢以特定方式执行任务时进行维护和切换。

在你的披萨例子中,如果你想做一个披萨,界面就是你所需要的,从那里每个披萨都有自己的逻辑。

这有助于减少耦合和圈复杂度。您仍然需要实现逻辑,但在更广泛的情况下,您需要跟踪的内容将更少。

对于每个披萨,您可以跟踪特定于该披萨的信息。其他披萨有什么并不重要,因为只有其他披萨需要知道。