-1

可能重复:
接口:为什么我似乎无法掌握它们?

要使用我刚刚发现的库,我需要先实现一些接口。但是有些方法似乎要求具有某些接口类型的对象......如果我有一个名为 MyInterface 的接口,我可以编写如下内容:

    MyInterface shoe;

这对我来说真的没有意义。有人可以教我这个概念吗?我读了这个: http: //www.dotnetperls.com/interface但它并没有真正帮助,我认为这个概念比这里介绍的要复杂一些。

谢谢 !

编辑 :

对于那些想知道的人,我对接口并不陌生,但这是我第一次遇到这样的使用它们。对于那些将我的问题降级的人,我确实进行了搜索,但显然很不走运。

4

6 回答 6

4

一个简单的解释:一个班级就像一个公司。如果它声称是销售公司,它必须提供销售服务。它自称是火车工厂,它必须能够制造火车。如果国家铁路要购买火车,它可以使用任何可以生产火车的公司。

接口描述了一个类必须能够做什么。这就像一份合同。每个想要拥有接口的类都必须履行该合同并能够执行合同规定的事情。类实例可以通过类方法执行动作。

但是,合同并没有说明班级应该如何做。所以一个类可以实现它想要的功能,或者换句话说,实现接口

public Train
{
    private price;
    public Train(float price) { this.price = price; }
}

public IMyInterface
{
   Train MakeTrain();
}

public ExpensiveTrainFactory : ITrainProducer
{
    // make a luxury, expensive train
    public Train MakeTrain() { return new Train(4000.0); }
}

public CheapTrainFactory : ITrainProducer
{
    // make a cheap train
    public Train MakeTrain() { return new Train(500.0); }
}

public NationalRailways
{
    List<Train> trains;
    public NationalRailways()
    {
        this.trains = new List<Train>();
    }
    public Train BuyTrain(ITrainProducer factory)
    {
        // you can call MakeTrain() because the ITrainProducer guarantees that it can make trains
        trains.Add(factory.MakeTrain());
    }
}

然后在您的代码中:

NationalRailways railway = new NationalRailways();
ExpensiveTrainFactory expFactory = new ExpensiveTrainFactory();
CheapTrainFactory cheapFactory = new CheapTrainFactory();

// expFactory implements ITrainProducer, so I can use it from BuyTrain(ITrainProducer)
railways.BuyTrain(expFactory);
// cheapFactory implements ITrainProducer, so I can use it from BuyTrain(ITrainProducer)  as well
railways.BuyTrain(cheapFactory);
于 2012-08-03T10:00:14.360 回答
3

您可以声明一个接口,就像在您的示例中一样。但是,您不能实例化一个。

MyInterface shoe = new MyInterface ();

以上不是合法代码。由于接口只是描述一个合约,它没有实现细节,这留给客户端代码(你)。因此,能够创建 MyInterface 的实际实例是没有意义的。

你可以做的是有一个类 SomeClass,实现 MyInterface 契约:

SomeClass: MyInterface
{
  //implement the methods of MyInterface. All of them, to fulfill the contract.
}

然后您可以执行以下操作:

MyInterface shoe = new SomeClass();

由于 SomeClass 实现了 MyInterface 合约,所以上面是合法的。您可以创建 SomeClass 的实例,因为它包含实现细节。

然后您可以在此基础上构建并创建更多实现 MyInterface 的类。

这样做的好处是你可以有一个方法,例如:

void someMethod (MyInterface test)
{

}

您可以将此方法传递给 SomeClass 对象或您创建的任何其他实现 MyInterface 的类。

然后在这个方法中,你可以在不知道传递给你的确切对象的情况下调用合约包含的方法。这使得编写未来的代码更容易。您可以创建新对象,只要它们实现 MyInterface,就可以将此对象传递给 someMethod 而无需更改方法的声明。

于 2012-08-03T10:03:51.883 回答
2

你是对的,你不能直接创建一个接口的实例。但是,您可以创建实现该接口的某种类型的实例。

说我有一个界面

public IMyInterface
{
   void DoSomething();
}

(注意:通常接口名称以“I”开头)

另外我有课

public MyClass: IMyInterface
{
    public void DoSomething() { ... }
}

那我可以做

IMyInterface something = new MyClass();

尽管您经常调用一些(工厂)方法来返回一些实现该接口的类,而不是直接执行new.

通过使用接口作为变量的类型,您可以指定您只对那里指定的方法和属性感兴趣。

于 2012-08-03T09:57:13.860 回答
2

在 C# 中,每个值都有两种不同的类型:表观类型和实际类型。表观类型是保存该值的变量的类型,而实际类型来自用于创建该值的构造函数。假设我们有以下类:

class MyClass : BaseClass, IMyInterface {
    /* ... */
}

那么以下所有声明都是有效的:

object obj1 = new MyClass();
IMyInterface obj2 = new MyClass();
BaseClass obj3 = new MyClass();
MyClass obj4 = new MyClass();

表观类型和实际类型如下:

object obj1 = new MyClass(); /* apparent: object, actual: MyClass */
IMyInterface obj2 = new MyClass(); /* apparent: IMyInterface, actual: MyClass */
BaseClass obj3 = new MyClass(); /* apparent: BaseClass, actual: MyClass */
MyClass obj4 = new MyClass(); /* apparent: MyClass, actual: MyClass */

当你操作一个对象(调用它的方法等)时,你会假设对象有它的明显类型——你不能调用任何特定于类的方法object。表观类型规定了对象外部可见的对象接口。

引擎盖下实际发生的事情是根据对象的实际类型完成的 - 例如,如果您覆盖ToString类的方法,则在以下代码中调用被覆盖的方法:

object obj = new MyClass();
Console.WriteLine(obj.ToString());

实际类型决定了对象的功能是如何实现的。

于 2012-08-03T10:07:13.673 回答
1

接口在类和调用它的代码之间建立了契约。它们还允许您拥有实现相同接口但执行不同操作或事件的类似类,而不必知道您实际使用的是哪个类。作为示例,这可能更有意义,因此让我根据您的链接使用相同的示例,并进行一些修改:

using System;

interface IPerl
{
    void Read();
}

class Test : IPerl
{
    public void Read()
    {
    Console.WriteLine("Read Test");
    }
}

class Test1 : IPerl
{
    public void Read()
    {
    Console.WriteLine("Read Test1");
    }
}

class Program
{
    static void Main()
    {
    IPerl perl = new Test(); // Create instance of Test.
    perl.Read(); // Call method on interface output will be different then Test1.

        perl = new Test1(); // Create instance of Test1.
    perl.Read(); // Call method on interface output will be different then Test.

    }
}

输出:

  1. “阅读测试”
  2. “阅读测试1”

我希望这会有所帮助。

谢谢 Ankur

于 2012-08-03T10:02:12.790 回答
0

什么是接口

接口基本上定义了类或结构的蓝图。接口的编程定义看起来非常类似于类,但没有实现任何东西。接口定义属性、方法、事件和索引器,但接口不定义任何这些的实现。它只是宣布它们的存在。接口实际上不会定义任何功能。它们只是定义了与类进行交互的方式。

什么接口不是

接口不应与继承相混淆。它们是两个非常不同的东西。继承会定义很多实现,并用于代码重用。接口只是对必须如何与实现类进行通信的定义。这就像一份书面合同。“签署”合同的类将同意以它希望的任何方式执行某些指定的操作,但它必须执行指定的操作。

何时使用接口

接口允许我们为类将要实现的内容创建漂亮的布局。由于接口给我们的保证,当许多组件使用相同的接口时,它允许我们轻松地将一个组件与另一个使用相同接口的组件互换。动态程序由此开始很容易形成。

有关更多信息,请访问有关Understanding_Interfaces_in_C#的帖子

于 2012-08-03T09:58:12.560 回答