目录
概述
有次需要实现一个接口(事实上它是 C++ virtual 中的延迟绑定),而 C# 也存在所谓 ‘接口’。但发现事实并不美好。
interface
首先,我们看代码
using System;
namespace test {
interface IDemo {
void doSome( );
}
class OneIDemo : IDemo {
public void doSome( ) {
Console.WriteLine( "OneIDemo : IDemo" );
}
}
class TwoIDemo : OneIDemo {
public new void doSome( ) {
Console.WriteLine( "TwoIDemo : OneIDemo" );
}
}
internal class TestMain {
private static void Main( string[] args ) {
OneIDemo idemo = new TwoIDemo( );
idemo.doSome( );
Console.ReadKey( );
}
}
}
现在我有一个理想的状态,它应该显示的是 “TwoIDemo : OneIDemo”,
但很可惜,显示给我打了一棒!它居然显示的是 "OneIDemo : IDemo"。
诚然,现实很残酷,所以我碰到另外一个关键字:abstract
abstract
using System;
namespace test {
abstract class IDemo {
public abstract void doSome( );
}
class OneIDemo : IDemo {
public override void doSome( ) {
Console.WriteLine( "OneIDemo : IDemo" );
}
}
class TwoIDemo : OneIDemo {
public override void doSome( ) {
Console.WriteLine( "TwoIDemo : OneIDemo" );
}
}
internal class TestMain {
private static void Main( string[] args ) {
OneIDemo idemo = new TwoIDemo( );
idemo.doSome( );
Console.ReadKey( );
}
}
}
结果很好,得到了我想要的输出:
被 override 和 new 关键字描述的函数方法
override
将会让函数方法进行延迟绑定的定义,就正如第二个案例一般,使用 OneIDemo 类型去接受 new TwoIDemo( ) 创建的对象,实际运行将会得到 TwoIDemo 一样,因为在 TwoIDemo 中,是‘ public override void doSome( ) ’ 这样声明的
new
将会让函数方法进行即时定义,若改成以下声明
using System;
namespace test {
abstract class IDemo {
public abstract void doSome( );
}
class OneIDemo : IDemo {
public override void doSome( ) {
Console.WriteLine( "OneIDemo : IDemo" );
}
}
class TwoIDemo : OneIDemo {
public new void doSome( ) {
Console.WriteLine( "TwoIDemo : OneIDemo" );
}
}
internal class TestMain {
private static void Main( string[] args ) {
OneIDemo idemo = new TwoIDemo( );
idemo.doSome( );
Console.ReadKey( );
}
}
}
同样运行
那么将会输出
" OneIDemo : IDemo"
注意
请不要在 interface 实现的类中使用 override 关键字声明函数,因为他会给你报一个错
但若是必须使用 interface 来实现延迟绑定,可以参考以下操作
interface 的延迟绑定
先给一段实现代码
using System;
namespace test {
interface IDemo {
void doSome( );
}
class OneIDemo : IDemo {
public virtual void doSome( ) {
Console.WriteLine( "OneIDemo : IDemo" );
}
}
class TwoIDemo : OneIDemo {
public override void doSome( ) {
Console.WriteLine( "TwoIDemo : OneIDemo" );
}
}
internal class TestMain {
private static void Main( string[] args ) {
OneIDemo idemo = new TwoIDemo( );
idemo.doSome( );
Console.ReadKey( );
}
}
}
运行发现会是一个友善的结果:
它显示 “TwoIDemo : OneIDemo” 了。
但不可否认,它需要借助一个实现类,并且该类重新声明 void doSome(),使它成为一个 virtual,之后再用 override 声明在实现类的子类之下。
愚蠢的想法
这样的话, interface 将会失去意义,变成一个奇特的 abstract 类,因为它是存在‘异议’的!
想象一下,我使用 ‘接口’ 其实是在类的多态上,但诚然做不到,改为了一个‘实现类’去实现它,但声明的接口仍然是那个 interface 的类,此时。我们是应该使用子类当做参数,还是使用 interface 声明的类当做参数了?若是后续开发的代码当中在应该实现该 interface 类使用 virtual 声明的时候没有声明,那结果应该是可怕的。
同样的,在 abstract 的子类当中使用 new 去覆盖,也是愚蠢的