接口具有下列属性:
-
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
-
不能直接实例化接口。
-
接口可以包含事件、索引器、方法和属性。
-
接口不包含方法的实现。
-
类和结构可从多个接口继承。
-
接口自身可从多个接口继承。
显示接口实现:
如果类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。例如:
interface IControl { void Paint(); } interface ISurface { void Paint(); } class SampleClass : IControl, ISurface { // Both ISurface.Paint and IControl.Paint call this method. public void Paint() { } }
然而,如果两个接口成员执行不同的函数,那么这可能会导致其中一个接口的实现不正确或两个接口的实现都不正确。可以显式地实现接口成员 -- 即创建一个仅通过该接口调用并且特定于该接口的类成员。这是使用接口名称和一个句点命名该类成员来实现的。例如:
public class SampleClass : IControl, ISurface { void IControl.Paint() { System.Console.WriteLine("IControl.Paint"); } void ISurface.Paint() { System.Console.WriteLine("ISurface.Paint"); } }
类成员 IControl.Paint 只能通过 IControl 接口使用,ISurface.Paint 只能通过 ISurface 使用。两个方法实现都是分离的,都不可以直接在类中使用。例如:
SampleClass obj = new SampleClass(); //obj.Paint(); // Compiler error. IControl c = (IControl)obj; c.Paint(); // Calls IControl.Paint on SampleClass. ISurface s = (ISurface)obj; s.Paint(); // Calls ISurface.Paint on SampleClass.
显式实现还用于解决两个接口分别声明具有相同名称的不同成员(如属性和方法)的情况:
interface ILeft { int P { get;} } interface IRight { int P(); }
为了同时实现两个接口,类必须对属性 P 和/或方法 P 使用显式实现以避免编译器错误。例如:
class Middle : ILeft, IRight { public int P() { return 0; } int ILeft.P { get { return 0; } } }
在类中声明事件,然后在适当的位置调用该事件。
public interface IDrawingObject
{
event EventHandler ShapeChanged;
}
public class MyEventArgs : EventArgs {…}
public class Shape : IDrawingObject
{
event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something before the event…
OnShapeChanged(new MyEventsArgs(…));
// or do something after the event.
}
protected virtual void OnShapeChanged(MyEventArgs e)
{
if(ShapeChanged != null)
{
ShapeChanged(this, e);
}
}
}