如果 类 实现两个接口,其中包含具有相同签名的成员,则在类上实现该成员将导致这两个接口使用该成员作为其实现。 如下示例中,所有对 Paint
的调用皆调用同一方法。 第一个示例定义类型:
public interface IControl
{
void Paint();
}
public interface ISurface
{
void Paint();
}
public class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
以下示例调用方法:
SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;
// The following lines all call the same method.
sample.Paint();
control.Paint();
surface.Paint();
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
但你可能不希望为这两个接口调用相同的实现。 若要根据正在使用的接口调用不同的实现,可以显式实现接口成员。 显式接口实现是仅通过指定接口调用的类成员。 通过在类成员前面加上接口名称和句点可命名该类成员。 例如:
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 sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;
// The following lines all call the same method.
//sample.Paint(); // Compiler error.
control.Paint(); // Calls IControl.Paint on SampleClass.
surface.Paint(); // Calls ISurface.Paint on SampleClass.
// Output:
// IControl.Paint
// ISurface.Paint
显式实现还用于解决两个接口分别声明相同名称的不同成员(如属性和方法)的情况。 若要实现这两个接口,类必须使用属性 P
的显式实现或方法 P
(或两者)以避免编译器错误。 例如:
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
显式接口实现没有访问修饰符,因为它不能作为其定义类型的成员进行访问。 相反,仅当通过接口实例调用时,才能访问它。 如果为显式接口实现指定访问修饰符,则会出现编译器错误 CS0106。 有关详细信息,请参阅 interface
(C# 参考)。
可以为在接口中声明的成员定义实现。 如果类从接口继承方法实现,则只能通过接口类型的引用访问该方法。 继承的成员不在公共接口中显示。 以下示例定义接口方法的默认实现:
public interface IControl
{
void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
// Paint() is inherited from IControl.
}
以下示例调用默认实现:
var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();
实现 IControl
接口的任何类都可以替代默认 Paint
方法(作为公共方法)或显式接口实现。