C# 接口
接口是使用 interface 关键字定义的。例如:
interface IComparable { int CompareTo(object obj); }
接口描述可属于任何类或结构的一组相关行为。接口可由方法、属性、事件、索引器或这四种成员类型的任何组合构成。接口不能包含字段。接口成员一定是公共(public)的。
类和结构可以像类继承基类或结构一样从接口继承,但有两个例外:
-
类或结构可继承多个接口。
-
当类或结构继承接口时,它继承成员定义但不继承实现。
若要实现接口成员,类中的对应成员必须是公共的、非静态的,并且与接口成员具有相同的名称和签名。
类的属性和索引器可以为接口上定义的属性或索引器定义额外的访问器。例如,接口可以声明一个带有 get 访问器的属性,而实现该接口的类可以声明同时带有 get 和 set 访问器的同一属性。但是,如果属性或索引器使用显式实现,则访问器必须匹配。
接口和接口成员是抽象的;接口不提供默认实现。
接口可以继承其他接口。类可以通过其继承的基类或接口多次继承某个接口。在这种情况下,如果将该接口声明为新类的一部分,则类只能实现该接口一次。如果没有将继承的接口声明为新类的一部分,其实现将由声明它的基类提供。基类可以使用虚拟成员实现接口成员;在这种情况下,继承接口的类可通过重写虚拟成员来更改接口行为。有关虚拟成员的更多信息,请参见多态性。
接口概述
接口可以是命名空间或类的成员
接口具有下列属性:
-
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
-
不能直接实例化接口。
-
接口可以包含事件、索引器、方法和属性。
-
接口不包含方法的实现。
-
类和结构可从多个接口继承。
-
接口自身可从多个接口继承
显式接口实现
如果类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。例如:
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 ISampleInterface { // Property declaration: string Name { get; set; } }
接口中的索引器
// Indexer on an interface: public interface ISomeInterface { // Indexer declaration: int this[int index] { get; set; } } // Implementing the interface. class IndexerClass : ISomeInterface { private int[] arr = new int[100]; public int this[int index] // indexer declaration { get { // Check the index limits. if (index < 0 || index >= 100) { return 0; } else { return arr[index]; } } set { if (!(index < 0 || index >= 100)) { arr[index] = value; } } } }
在接口中声明一个事件,然后在类中实现该事件
public delegate void TestDelegate(); // delegate declaration public interface ITestInterface { event TestDelegate TestEvent; void FireAway(); } public class TestClass : ITestInterface { public event TestDelegate TestEvent; public void FireAway() { if (TestEvent != null) { TestEvent(); } } } public class MainClass { static private void F() { System.Console.WriteLine("This is called when the event fires."); } static void Main() { ITestInterface i = new TestClass(); i.TestEvent += new TestDelegate(F); i.FireAway(); } }
显式实现接口成员
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_csref/html/514cde76-f981-474e-8b40-9493619f899c.htm
使用继承显式实现接口成员
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_csref/html/8b402ddc-dff9-4869-89cb-d718c764e68e.htm