C#interface instance-like …帮我理解

C# interface instance-like… help me understand

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Interfaces: Why can't I seem to grasp them?

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

1
    MyInterface shoe;

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

谢谢!

编辑:

对于那些想知道的人来说,我对接口并不陌生,但这是我第一次使用它们。对于那些贬低我问题的人,我确实在寻找,但显然是不幸的。


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

接口描述类必须能够做什么。这就像一份合同。每一个想要有一个接口的类都必须完成这个契约,并且能够按照契约所说的去做。类实例可以通过类方法执行操作。

然而,合同并没有说明该如何做。所以类可以实现它想要的功能,或者换句话说,实现接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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());
    }
}

然后在你的代码中:

1
2
3
4
5
6
7
8
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);


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

1
MyInterface shoe = new MyInterface ();

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

您可以做的是,创建一个类someClass,实现myInterface契约:

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

然后你可以做如下的事情:

1
MyInterface shoe = new SomeClass();

由于SomeClass实现了MyInterface合同,因此上述内容是合法的。您可以创建SomeClass的实例,因为它包含实现细节。

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

这样做的好处在于,您可以使用一种方法,例如:

1
2
3
4
void someMethod (MyInterface test)
{

}

您可以将这个方法传递给someClass对象或您创建的任何其他实现myInterface的类。

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


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

1
2
3
class MyClass : BaseClass, IMyInterface {
    /* ... */
}

则以下所有声明均有效:

1
2
3
4
object obj1 = new MyClass();
IMyInterface obj2 = new MyClass();
BaseClass obj3 = new MyClass();
MyClass obj4 = new MyClass();

表观和实际类型如下:

1
2
3
4
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方法,则在以下代码中调用重写的方法:

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

实际类型指示如何实现对象的功能。


您是正确的,不能直接创建接口的实例。但是,您可以创建实现该接口的某种类型的实例。

假设我有一个接口

1
2
3
4
public IMyInterface
{
   void DoSomething();
}

(注:通常以"i"开头的接口名称)

另外我还有个班

1
2
3
4
public MyClass: IMyInterface
{
    public void DoSomething() { ... }
}

然后我可以做

1
IMyInterface something = new MyClass();

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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.

    }
}

输出:

  • "阅读测试"
  • "读取TEST 1"
  • 我希望这会有所帮助。

    谢谢你


    什么接口

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

    什么接口不是

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

    何时使用接口

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

    欲了解更多信息,请访问本帖了解#