Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 接口—;什么';重点是什么?_C#_.net_Interface - Fatal编程技术网

C# 接口—;什么';重点是什么?

C# 接口—;什么';重点是什么?,c#,.net,interface,C#,.net,Interface,我真的找不到接口的原因。据我所知,这是一种解决C#中不存在的不存在的多重继承问题的方法(至少我被告知) 我所看到的是,您预定义了一些成员和函数,然后必须在类中重新定义它们。从而使接口冗余。这感觉就像是句法上的…嗯,对我来说是垃圾(请不要冒犯我的意思,垃圾就是无用的东西) 下面给出的例子取自堆栈溢出上的另一个C#interfaces线程,我只创建一个名为Pizza的基类,而不是接口 class Program { static void Main(string[] args) {

我真的找不到接口的原因。据我所知,这是一种解决C#中不存在的不存在的多重继承问题的方法(至少我被告知)

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

下面给出的例子取自堆栈溢出上的另一个C#interfaces线程,我只创建一个名为Pizza的基类,而不是接口

class Program {
    static void Main(string[] args) {
        IMachine machine = new Machine();
        machine.Run();
        Console.ReadKey();
    }

}

class Machine : IMachine {
    private void Run() {
        Console.WriteLine("Running...");
    }
    void IMachine.Run() => Run();
}

interface IMachine
{
    void Run();
}
简单示例(取自不同的堆栈溢出贡献)


考虑一下你不能在C#中使用多重继承,然后再看看你的问题

关键是接口代表一个契约。任何实现类都必须具有的一组公共方法。从技术上讲,接口只控制语法,即有哪些方法、它们得到哪些参数以及它们返回什么。通常它们也封装了语义,尽管这只是通过文档实现的

然后,您可以拥有一个接口的不同实现,并随意交换它们。在您的示例中,由于每个pizza实例都是
IPizza
,因此无论您在哪里处理未知pizza类型的实例,都可以使用
IPizza
。任何类型继承自
IPizza
的实例都保证是可排序的,因为它有一个
Order()
方法

Python不是静态类型,因此在运行时保留并查找类型。因此,您可以尝试在任何对象上调用
Order()
方法。只要对象有这样一个方法,运行时就会很高兴,如果没有,可能只是耸耸肩说“Meh.”。在C#中并非如此。编译器负责进行正确的调用,如果它只是有一些随机的
对象
,编译器还不知道运行时的实例是否会有该方法。从编译器的角度来看,它是无效的,因为它无法验证它。(你可以用反射或
动态
关键字来做这些事情,但我想这现在有点过分了。)


还请注意,通常意义上的接口不一定必须是C#
接口
,它也可以是抽象类,甚至是普通类(如果所有子类都需要共享一些公共代码,那么这就很方便了–然而,在大多数情况下,
接口
就足够了)。

接口=契约,用于(见附件).

如果没有在Python中使用的as,C#依赖接口来提供抽象。如果类的依赖项都是具体类型,则不能传入任何其他类型-使用接口可以传入实现该接口的任何类型。

接口定义了某个类的提供者之间的契约功能性和相应的消费者。它将实现与契约(接口)分离。您应该了解面向对象的体系结构和设计。您可能希望从wikipedia开始:

以下是重新解释的示例:

public interface IFood // not Pizza
{
    public void Prepare();

}

public class Pizza : IFood
{
    public void Prepare() // Not order for explanations sake
    {
        //Prepare Pizza
    }
}

public class Burger : IFood
{
    public void Prepare()
    {
        //Prepare Burger
    }
}
class Program {
    static void Main(string[] args) {
        IMachine machine = new Machine();
        machine.Run();
        Console.ReadKey();
    }

}

class Machine : IMachine {
    private void Run() {
        Console.WriteLine("Running...");
    }
    void IMachine.Run() => Run();
}

interface IMachine
{
    void Run();
}

接口实际上是实现类必须遵循的契约,它实际上是我所知道的几乎所有设计模式的基础

在您的示例中,创建接口是因为Pizza的任何内容(这意味着实现Pizza接口)都保证已实现

public void Order();
在您提到的代码之后,您可以有如下内容:

public void orderMyPizza(IPizza myPizza) {
//This will always work, because everyone MUST implement order
      myPizza.order();
}
foreach (Control ctrl in Controls)
{
    if (ctrl is MyThemableButton)
        ((MyThemableButton)ctrl).SetTheme(newTheme);
    else if (ctrl is MyThemableTextBox)
        ((MyThemableTextBox)ctrl).SetTheme(newTheme);
    else if (ctrl is MyThemableGridView)
        ((MyThemableGridView)ctrl).SetTheme(newTheme);
    else ....
}
ITradesman tradie = Tradesman.Factory(); // in reality i know it's a plumber, but in the real world you won't know who's on the other side of the tradie assignment.

tradie.Work(); // and then tradie will do the work of a plumber, or electrician etc. depending on what type of tradesman he is. The foreman doesn't need to know anything, apart from telling the anonymous tradie to get to Work()!!

通过这种方式,您使用的是多态性,您所关心的只是对象对order()的响应。

Pizza示例很糟糕,因为您应该使用一个抽象类来处理排序,而Pizza应该只覆盖Pizza类型,例如

当您有一个共享属性,但您的类从不同的地方继承时,或者当您没有任何可以使用的公共代码时,您可以使用接口。例如,这是可以被释放的东西
IDisposable
,您知道它将被释放,但您不知道当它被释放时会发生什么

接口只是一个协定,它告诉您对象可以做的一些事情,哪些参数和期望的返回类型。

在这种情况下,您可以(也可能会)定义一个Pizza基类并从中继承。但是,接口允许您做其他方式无法实现的事情有两个原因:

  • 一个类可以实现多个接口。它只定义了该类必须具备的功能。实现一系列接口意味着一个类可以在不同的地方实现多个功能

  • 可以在比类或调用方更大的范围内定义接口。这意味着您可以分离功能,分离项目依赖项,并将功能保留在一个项目或类中,并将此功能的实现保留在其他地方


  • 2的一个含义是,您可以更改正在使用的类,只需要它实现适当的接口。

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

    如果我正在工作在绘制形状的API上,我可能希望使用DirectX或图形调用,或OpenGL。因此,我将创建一个接口,该接口将从您的调用中抽象出我的实现

    class Program {
        static void Main(string[] args) {
            IMachine machine = new Machine();
            machine.Run();
            Console.ReadKey();
        }
    
    }
    
    class Machine : IMachine {
        private void Run() {
            Console.WriteLine("Running...");
        }
        void IMachine.Run() => Run();
    }
    
    interface IMachine
    {
        void Run();
    }
    
    因此您调用一个工厂方法:
    MyInterface i=MyGraphics.getInstance()
    。然后,您有一个合同,这样您就知道在
    MyInterface
    中可以使用哪些函数。这样,您就可以调用
    i.drawRectangle
    i.drawCube
    ,并且知道如果您将一个库换成另一个库,那么这些函数是受支持的

    如果在XML fi中使用依赖项注入,那么这一点就变得更加重要
    public class Pizza()
    {
        public void Prepare(PizzaType tp)
        {
            switch (tp)
            {
                case PizzaType.StuffedCrust:
                    // prepare stuffed crust ingredients in system
                    break;
    
                case PizzaType.DeepDish:
                    // prepare deep dish ingredients in system
                    break;
    
                //.... etc.
            }
        }
    }
    
    public interface IPizza
    {
        void Prepare();
    }
    
    public class StuffedCrustPizza : IPizza
    {
        public void Prepare()
        {
            // Set settings in system for stuffed crust preparations
        }
    }
    
    public class DeepDishPizza : IPizza
    {
        public void Prepare()
        {
            // Set settings in system for deep dish preparations
        }
    }
    
    public PreparePizzas(IList<IPizza> pizzas)
    {
        foreach (IPizza pizza in pizzas)
            pizza.Prepare();
    }
    
    // This is our back-end implementation of a troll
    class Troll
    {
        void Walk(int distance)
        {
            //Implementation here
        }
    }
    
    function SpawnCreature()
    {
        Troll aTroll = new Troll();
        
        aTroll.Walk(1);
    }
    
    class Orc
    {
        void Walk(int distance)
        {
            //Implementation (orcs are faster than trolls)
        }
    }
    
    void SpawnCreature(creatureType)
    {
        switch(creatureType)
        {
             case Orc:
    
               Orc anOrc = new Orc();
               anORc.Walk();
    
              case Troll:
    
                Troll aTroll = new Troll();
                 aTroll.Walk();
        }
    }
    
    interface ICreature
    {
        void Walk(int distance)
    }
    
    public class Troll : ICreature
    public class Orc : ICreature 
    
    //etc
    
    void SpawnCreature(creatureType)
    {
        ICreature creature;
    
        switch(creatureType)
        {
             case Orc:
    
               creature = new Orc();
    
              case Troll:
    
                creature = new Troll();
        }
    
        creature.Walk();
    }
    
    public class CreatureFactory {
    
     public ICreature GetCreature(creatureType)
     {
        ICreature creature;
    
        switch(creatureType)
        {
             case Orc:
    
               creature = new Orc();
    
              case Troll:
    
                creature = new Troll();
        }
    
        return creature;
      }
    }
    
    CreatureFactory _factory;
    
    void SpawnCreature(creatureType)
    {
        ICreature creature = _factory.GetCreature(creatureType);
    
        creature.Walk();
    }
    
    interface ICanTurnToStone
    {
       void TurnToStone();
    }
    
    public class Troll: ICreature, ICanTurnToStone
    
    void SpawnCreatureInSunlight(creatureType)
    {
        ICreature creature = _factory.GetCreature(creatureType);
    
        creature.Walk();
    
        if (creature is ICanTurnToStone)
        {
           (ICanTurnToStone)creature.TurnToStone();
        }
    }
    
    public interface ICreatureFactory {
         ICreature GetCreature(string creatureType);
    }
    
    public class CreatureController : Controller {
    
       private readonly ICreatureFactory _factory;
    
       public CreatureController(ICreatureFactory factory) {
         _factory = factory;
       }
    
       public HttpResponseMessage TurnToStone(string creatureType) {
    
           ICreature creature = _factory.GetCreature(creatureType);
       
           creature.TurnToStone();
    
           return Request.CreateResponse(HttpStatusCode.OK);
       }
    }
    
    interface IRectangular
    {
        Int32 Width();
        Int32 Height();
    }
    
    static class Utils
    {
        public static Int32 Area(IRectangular rect)
        {
            return rect.Width() * rect.Height();
        }
    }
    
    class SwimmingPool : IRectangular
    {
        int width;
        int height;
    
        public SwimmingPool(int w, int h)
        { width = w; height = h; }
    
        public int Width() { return width; }
        public int Height() { return height; }
    }
    
    class House : IRectangular
    {
        int width;
        int height;
    
        public House(int w, int h)
        { width = w; height = h; }
    
        public int Width() { return width; }
        public int Height() { return height; }
    }
    
    var house = new House(2, 3);
    
    var pool = new SwimmingPool(3, 4);
    
    Console.WriteLine(Utils.Area(house));
    Console.WriteLine(Utils.Area(pool));
    
    public abstract class Food {
        public abstract void Prepare();
    }
    
    public class Pizza : Food  {
        public override void Prepare() { /* Prepare pizza */ }
    }
    
    public class Burger : Food  {
        public override void Prepare() { /* Prepare Burger */ }
    }
    
    public abstract class MenuItem {
        public string Name { get; set; }
        public abstract void BringToTable();
    }
    
    // Notice Soda only inherits from MenuItem
    public class Soda : MenuItem {
        public override void BringToTable() { /* Bring soda to table */ }
    }
    
    
    // All food needs to be cooked (real food) so we add this
    // feature to all food menu items
    public interface IFood {
        void Cook();
    }
    
    public class Pizza : MenuItem, IFood {
        public override void BringToTable() { /* Bring pizza to table */ }
        public void Cook() { /* Cook Pizza */ }
    }
    
    public class Burger : MenuItem, IFood {
        public override void BringToTable() { /* Bring burger to table */ }
        public void Cook() { /* Cook Burger */ }
    }
    
    public class Waiter {
        public void TakeOrder(IEnumerable<MenuItem> order) 
        {
            // Cook first
            // (all except soda because soda is not IFood)
            foreach (var food in order.OfType<IFood>())
                food.Cook();
    
            // Bring them all to the table
            // (everything, including soda, pizza and burger because they're all menu items)
            foreach (var menuItem in order)
                menuItem.BringToTable();
        }
    }
    
    If(electrician) then  electrician.FixCablesAndElectricity() 
    
    if(plumber) then plumber.IncreaseWaterPressureAndFixLeaks() 
    
    ITradesman tradie = Tradesman.Factory(); // in reality i know it's a plumber, but in the real world you won't know who's on the other side of the tradie assignment.
    
    tradie.Work(); // and then tradie will do the work of a plumber, or electrician etc. depending on what type of tradesman he is. The foreman doesn't need to know anything, apart from telling the anonymous tradie to get to Work()!!
    
    class Program {
        static void Main(string[] args) {
            IMachine machine = new Machine();
            machine.Run();
            Console.ReadKey();
        }
    
    }
    
    class Machine : IMachine {
        private void Run() {
            Console.WriteLine("Running...");
        }
        void IMachine.Run() => Run();
    }
    
    interface IMachine
    {
        void Run();
    }
    
    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();
            }
    }
    
    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();
    
        }
    }
    
    interface ICRUD{
          void InsertData(); // will insert data
          void UpdateData(); // will update data
          void DeleteData(); // will delete data
    }