混淆界面

本文关键字:界面 | 更新日期: 2023-09-27 18:12:48

我是c#新手。现在在阅读界面的时候。我很困惑。我在MSDN上读到,我们不能直接实例化接口。后来他们写了下面的例子:

Public interface ICat
{
   meow();
}
Public class Cat : ICat
{
   meow(){//do something }
}
////////////////////
static void main(){
Icat cat = new Cat();
Cat cat1 = nes Cat();
}

如果我们不能直接实例化接口,那么这一行的 Icat cat = new Cat(); 的意义是什么?这两者的区别是什么?

混淆界面

这两行都实例化了Cat的实例。不同之处在于,其中一个被赋值给类型为ICat变量。

ICat cat = new Cat();
Cat cat1 = nes Cat();

因此,当通过cat变量访问Cat实例时,您只能调用在ICat上声明的方法。当使用cat1时,可以访问Cat类的其他成员。

如果你在任何变量上调用GetType,你将返回Cat,因为这是你拥有的实例的类型。

另一个区别是,如果有另一个实现ICat的类,你可以将它的实例分配给cat变量,但你将无法将它分配给cat1,除非它继承了Cat:

Public class OtherCat : ICat
{
   meow(){//do something }
}
cat = new OtherCat();
// cat1 = new OtherCat(); // fails

第一个示例中的接口没有被实例化,而是实例化的Cat()实例的类型被声明为ICat类型,而不是Cat类型。

在你的特殊例子中,这不是很有趣。但是,考虑一个具有以下声明的接口:

public interface ICat
{
   Meow();
   Run();
   Hunt();
}

一旦这个接口被应用到多个具体类型,行为就可以被应用到各种各样的类中,同时一致地实现相同的行为。

public class Lion : ICat 
{
    public void Roar();
    public void Meow();
    public void Run();
    public void Hunt();
}
public class Tiger : ICat 
{
    public void Meow();
    public void Run();
    public void Hunt();
}
ICat lion = new Lion();
ICat tiger = new Tiger();

两个具体实例都可以从接口保证的所有三种方法中受益,并且只能从接口保证的方法中受益,除非转换为它们的具体类型。这提供了跨行为的一致性。但是请注意,这并不是实例化接口。它只将具体实例分配给共享接口类型,这是语言允许的。

结果:

lion.Run();tiger.Run()是完全允许的。

然而,

lion.Roar()将无法编译,因为它不受接口的保证。也就是说,如果您转换为实际实例化并随后分配给接口的底层具体类型,那么除了接口的方法之外,您还可以访问该类型的方法。

((Lion)lion).Roar();
同样

:

Lion concreteLion = new Lion();

在实例化时不分配给接口。因此,它可以直接访问接口保证的所有三个方法,并且它可以调用concreteLion.Roar()而不需要强制转换,因为实例已直接分配给具体类型,而不是由Lion类实现的接口。

首先让我们来定义什么是interface

一个interface可以被认为是一个契约,在这个意义上,一个类必须实现在给定接口(契约)内定义的任何东西。例如,假设我正在设计一个interface来定义汽车的行为。

接口将包含两个关键行为。

public interface ICar 
{
    void Accelerate();
    void Brake();
}  

你永远不能实例化interface,因为interface只是一个契约,一个class必须实现的定义,从interface派生的class将实现在它派生的interface中定义的所有属性和方法。Interfaces通常用于减少代码库中的依赖,如本答案所示。

继续上面的例子,人类驾驶汽车,但是有成千上万种不同的汽车,并且大多数汽车的实现方式不同,然而,这对人类来说应该无关紧要,如果你有能力驾驶一辆汽车,你应该能够驾驶所有的汽车。(这里只是概括一下,以保持简单)。

因此你需要做的是实例化一个class,它实现了ICar interface,任何人都可以把它作为一个驱动器…

void Main()
{
    Human jamesDoe = new Human();
    ICar car = new BMW();
    jamesDoe.TestDriveCar(car);
}
public interface ICar 
{
    void Accelerate();
    void Brake();
}  
public class BMW : ICar
{
    private int x;
    public void Accelerate()
    {
        new int[150].ToList()
                    .ForEach(i => { Console.WriteLine("{0} MPH", x++); Thread.Sleep(50); });
    }
    public void Brake()
    {
        new int[150].ToList()
                    .ForEach(i => { Console.WriteLine("{0} MPH", x--); Thread.Sleep(50); });
    }
}
public class Human
{
    public void TestDriveCar(ICar car)
    {
        car.Accelerate();
        car.Brake();
    }
}

我认为对我来说最好的描述是:

public interface IAnimal
{
    void ShowVoice();
}
public class Cat : IAnimal
{
    public void WiggleTail()
    {
        Console.Write("Wiggling tail...")
    }
    public void ShowVoice()
    {
        Console.Write("meow");
    }
}
public class Dog : IAnimal
{
    public void GivePaw()
    {
        Console.Write("Giving paw...")
    }
    public void ShowVoice()
    {
        Console.Write("woof");
    }
}
public static void main(){
    IAnimal cat = new Cat();
    IAnimal dog = nes Dog();
    cat.ShowVoice();
    //cat.WiggleTail(); - cannot do that on interface
    dog.ShowVoice();
    //dog.GivePaw(); - cannot do that on interface
    Cat catInst = new Cat();  
    Dog dogInst = new Dog(); 
    catInst.WiggleTail(); // you can do that because it is not an interface that we make call to
    dogInst.GivePaw(); //the same as with cat
    // catInst.GivePaw(); - cannot do this because it does not exist in the class
}

定义接口时,定义泛型情况,当类实现该接口时,定义特定情况。以

为例
interface IVehicle 
{
    int noOfWheels;
    float price;
}
class TwoWheeler : IVehicle
{
    public TwoWheeler(float price)
    {
       this.noOfWheels = 2;
       this.price = price;
    }
}
class FourWheeler : IVehicle
{
     public FourWheeler(float price)
     {
         this.noOfWheels = 4;
         this.price = price;
     }
}
class VehicleBill
{
   IVehicle vehicle;
   public static void main()
   {
      Console.Write("enter your choice
              'n 1. Two wheeler
              'n 2. Four Wheeler");
      int ch = Conver.toInt32(console.Read());
     //Here we decide which class is to be used for initialization
      if(ch == 1)
        vehicle = TwoWheeler(80000);
     else if(ch == 2)
        vehicle = FourWheeler(500000);
   }
}