前言:
当我们定义接口的成员的时候不需要写访问控制符,因为它是默认public的,也只能是public.当一个类要实现这个接口的时候,自然要公开其成员。一直以来我都这么做。
interface Interface1
{
string GetName(string name);
}
class Class1:Interface1
{
public string GetName(string name)
{
return name;
}
}
}
然而这么做并没有错。直到我学习控件开发的时候,发现了原来接口可以这么来实现。
public class DropDownList : ListControl, IPostBackDataHandler
{
protected virtual bool LoadPostData(string postDataKey,
NameValueCollection postCollection)
{
return false;
}
protected virtual void RaisePostDataChangedEvent()
{
}
bool IPostBackDataHandler.LoadPostData(string postDataKey,
NameValueCollection postCollection)
{
return this.LoadPostData(postDataKey, postCollection);
}
void IPostBackDataHandler.RaisePostDataChangedEvent()
{
this.RaisePostDataChangedEvent();
}
}
LoadPostData和RaisePostData方法是Page调用的,但却没有公开这两个方法。调用的时候不能用类的实例来调用,只能用接口的引用来调用,从而实现实现接口的实例只能被接口的引用调用的目的。
从此我就想到安全接口这个名称(不知道合理否),在编程中,我亦可以这么使用。
class Class1:Interface1
{
private string GetName(string name)
{
return name;
}
string Interface1.GetName(string name)
{
name += " interface";
return GetName(name);
}
}
class Program
{
static void Main(string[] args)
{
Class1 c = new Class1();
Interface1 i = (Interface1)c;
System.Console.WriteLine(i.GetName("Eric Wen"));
}
}
我觉得这样更符合oo,接口的方法不会泛用,实现和调用都和清晰。
后续:
看了回复后知道这种情况就是显示实现接口(Explicit interface member implementations)。
显示实现接口说明:
1、不能在方法调用、属性访问以及索引指示器访问中通过全权名访问显式接口成员执行体。事实上,显式接口成员执行体只能通过接口的实例,仅仅引用接口的成员名称来访问。
2、显式接口成员执行体不能使用任何访问限制符,也不能加上abstract, virtual, override或static 修饰符。
3、显式接口成员执行体和其他成员有着不同的访问方式。因为不能在方法调用、属性访问以及索引指示器访问中通过全权名访问,显式接口成员执行体在某种意义上是私有的。但它们又可以通过接口的实例访问,也具有一定的公有性质。
4、只有类在定义时,把接口名写在了基类列表中,而且类中定义的全权名、类型和返回类型都与显式接口成员执行体完全一致时,显式接口成员执行体才是有效的
5、如果一个类中既显示又隐式的实现了接口,这是显示元素只能通过接口的引用来直接访问,隐式元素只可以通过类来直接访问。
为什么要显示实现接口呢,目的:
1、因为显式接口成员执行体不能通过类的实例进行访问,这就可以从公有接口中把接口的实现部分单独分离开。如果一个类只在内部使用该接口,而类的使用者不会直接使用到该接口,这种显式接口成员执行体就可以起到作用。
2、显式接口成员执行体避免了接口成员之间因为同名而发生混淆。如果一个类希望对名称和返回类型相同的接口成员采用不同的实现方式,这就必须要使用到显式接口成员执行体。如果没有显式接口成员执行体,那么对于名称和返回类型不同的接口成员,类也无法进行实现。