您的位置:首页 > 其它

设计模式-派生类实现非虚接口的陷阱

2017-03-04 17:24 405 查看
作者:vuefine

文献: msdn library

平台:.NET 2.0+

理解接口方法和虚方法的区别

  第一眼看来,实现接口和覆写虚方法似乎没有什么区别,实际上,实现接口和覆写虚方法之间的差别很大!!!

派生不能覆写接口的非虚成员

  接口中声明的成员方法默认情况下并非虚方法,所以,派生类不能覆写基类中实现接口的非虚成员。

看一个例子。

定义接口ITest:

public interface ITest
{
void Test();
}


实现接口的Base类和Derive类

public class Base:ITest
{
public Base()
{
Console.WriteLine("This is base constructor");
}
//实现ITest接口
public void Test()
{
Console.WriteLine("This is in base to ITest implement");
}
}

public class Derive :Base,ITest
{
public Derive()
{
Console.WriteLine("This is derived constructor");

}
//测试Derive类实现了ITest吗??
public void Test()
{
Console.WriteLine("This is in Derive to ITest implement");
}
}


调用对象Base和Derive:

Base b = new Base();
b.Test();

Base d = new Derive();//将d声明为Base对象
d.Test();
Console.ReadLine();


输出结果为:



  可以看出,b和d实例的Test方法实现的行为都是位于基类的!!!这表明了,派生类不能覆写基类中实现接口的成员(非虚方法)

但是,请看下面调用:

Base b = new Base();
b.Test();
Derive d = new Derive(); //将d声明为Derive对象
d.Test();
Console.ReadLine();


输出结果为:



因此,如果想要继承的对象调用接口实现方法,只能声明为Derive实例。这样做不符合Effective C#中变量都声明为基实例的原则!!!

派生类方法个性,将基类方法转为虚方法

  避免这种使用上的混淆,如果确实派生类实现方法是个性行为,那么需要将基类的实现接口的方法前加virtual修饰符!

代码修改如下:

public class Base:ITest
{
public Base()
{
Console.WriteLine("This is base constructor");
}
public virtual void Test() //实现ITest接口的虚方法
{
Console.WriteLine("This is in base to ITest implemnt");
}
}

public class Derive :Base,ITest
{
public Derive()
{
Console.WriteLine("This is derived constructor");

}
public override void Test() //实现接口ITest的复写方法
{
Console.WriteLine("This is in Derive to ITest implemnt");
}
}


一次实现,多个关联对象使用

  观察上面的代码,我们发现,在基类中实现的接口,如果派生类也想实现此接口,那么它默认继承了基类的接口实现,所以不用重复写代码实现接口。

public interface ITest
{
void Test();
}

public class Base:ITest
{
public Base()
{
Console.WriteLine("This is base constructor");
}
public void Test()
{
Console.WriteLine("This is in base to ITest implemnt");
}
}

public class Derive :Base,ITest
{
public Derive()
{
Console.WriteLine("This is derived constructor");

}
}


总结:

1、 派生不能覆写接口的非虚成员;

2、如果派生类方法是个性方法,将基类方法转为虚方法;

3、若基类实现了接口方法,将派生类也显示地继承此接口,但是不用再次实现了!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐