我现在正在使用C#和.NET一段时间,尽管我以前一直在使用OOP语言(更准确地说是Java),但在使用.NET应用程序时我发现接口使用的不仅仅是我在Java中看到过。我根本没有很多经验,所以我不是说接口在.NET中更常用,但现在我觉得需要深入了解接口以及让人们经常使用它们的好处是什么
我在互联网上有一些东西,有些东西在这里,对我来说最有意义的解释就是这个 - How will I know when to create an interface?。
这是我的问题。我根本不期待接口的一些神奇的解释,因为我已经阅读了足够的东西,看不到这样的事情。我希望通过经验和编码,更深层次的理解将会自行实现,因此我决定尝试使用链接中接受的答案中的接口的优点。我也会在这里复制粘贴它:
你有4种不同类型的a,b,c,d。在你的代码中你有类似的东西:
a.Process();
b.Process();
c.Process();
d.Process();
为什么不让他们实施IProcessable
,然后再做
List<IProcessable> list;
foreach(IProcessable p in list)
p.Process();
当您添加50种类型的类时,这会扩展得更好。
问题是我似乎没有这个。在我阅读之后,我打开我的Visual Studio 2010并尝试重新创建这样的示例 - 我创建了一个项目并创建了四个类 - a
,b
,c
,{{1} }。所有这些课程都是一样的:
d
只有4个不同的名称和方法using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class a : ITest
{
public void Test()
{
System.Console.WriteLine("Hi from a");
}
}
}
打印名称。这是界面:
Test()
根据我在using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
interface ITest
{
public void Test();
}
}
中的理解,我有这个:
Program.cs
好。看来我真的搞错了。我认为通过实现相同的接口,我可以自动获取所有类的列表并使用它们,例如在上面的using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
List<ITest> list;
static void Main(string[] args)
{
foreach (ITest p in list)
p.Test();
}
}
}
方法中。但是我收到以下错误:
非静态字段,方法或属性需要对象引用
那么,有人可以降低我的水平并根据这个例子向我解释我是如何通过使用界面获得这样的好处。
答案 0 :(得分:3)
此处的问题与界面无关,但与课程Program
无关。字段list
是实例成员,而方法Main
是静态的。正如例外所述,您无法从静态方法引用非静态成员。
此外,list
从未实例化或初始化(至少不在您发布的代码段内)。因此,即使list
被声明为静态,您的代码也会产生NullReferenceException
。
尝试将Program
课程更改为:
class Program
{
static List<ITest> list;
static void Main(string[] args)
{
list = new List<ITest>();
// ...
// initialize list
// ...
foreach (ITest p in list)
p.Test();
}
}
答案 1 :(得分:1)
关于您的错误,看起来list
没有实例化,它是一个实例字段,可以从静态方法访问。
接口不是用于继承,而是用于多态。
接口不用于保存代码。如果您需要这样做,请使用Abstract classes。
所有接口都保证编译器您的类将以特定方式运行。它没有具体说明实现。
例如,List
和LinkedList
都有不同的含义,但它们都符合IEnumberable
接口,因此可以在foreach
中迭代环
答案 2 :(得分:1)
您的代码在创建将实现该接口的类方面看起来很好。问题似乎在于你的初始化。
在声明时,List<ITest> list
不是静态字段。 Main
函数是一个静态方法,因此它只能访问其他静态字段。
如果您想继续这个基本示例,请尝试将list
设置为静态字段,或将其设置为Main
中的变量,并将其实例化,在将其用于您的某些对象之前填充它foreach
循环。
答案 3 :(得分:0)
接口的使用定义了类似于对象占位符的东西,它肯定会有一些特定的行为,而实际上并不知道它。例如,您可以拥有A类和B类,它们都实现了IMyInterface。如果你需要一个IMyInterface实例,你可以使用它们并调用接口中指定但在A或B中实现的方法。此外,在IoC容器中有很好的基于约定的接口用法。