A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈涛 黑马帝   /  2011-11-3 11:58  /  4815 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

RT:大家都来谈谈接口、类和虚函数之间的区别?

7 个回复

倒序浏览
这些数据类型之间没有可比性
回复 使用道具 举报
接口中可以实现多继承,在继承其接口的类中必需实现接口中声明的全部方法。类只能单继承。不知道你说的“虚函数”是什么意识?是virtual吗?
回复 使用道具 举报
粗略的看一下,感觉实现接口和虚函数重载是一样的。你定义了一些对象,但是这些对象是在另一个类型里申明的。你被第一感觉骗了,实现接口与虚函数重载是完全不同的。在接口里定义的成员默认情况下,是根本不存在实际内容的。

派生类不能重载基类中的接口成员。接口可以隐式的实现,就是把它们从类的公共接口中隐藏。它们的概念是不同的而且使用也是不同的。

但你可以这样的实现接口:让你的派生类可以修改你的实现。你只用对派生类做一个Hook就行了。(译注:相信写过C++程序的人就知道hook是什么意思,而且我也实在想不到把hook译成什么比较好,所以就直接用hook这个原词了,就像bug一样。)

为了展示它们的不同之处,试着做一个简单的接口以及在一个类中实现它:

interface IMsg
{
void Message();
}

public class MyClass : IMsg
{
public void Message()
{
Console.WriteLine( "MyClass" );
}
}

Message()方法是MyClass的公共接口,Message同样可以用一个接口指针IMsg来访问。现在让我们来一点繁杂的,添加一个派生类:

public class MyDerivedClass : MyClass
{
public new void Message()
{
Console.WriteLine( "MyDerivedClass" );
}
}

注意到,我添加了一个关键字new在Message方法上,用于区别前面的一个Message(参见原则29)。MyClass.Message()不是虚函数,派生类可以不提供重载版本。MyDerived类创建了一个新的Message方法,但这个方法并不是重载MyClass.Message:它隐藏了原来的方法。而且,MyClass.Message还是可以通过IMsg的引用来访问:

MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyClass"

接口方法不是虚的,当你实现一个接口时,你就要在详细的相关类型中申明具体的实现内容。

但你可能想要创建接口,在基类中实现这些接口而且在派生类中修改它们的行为。这是可以办法到的。你有两个选择,如果不访问基类,你可以在派生类中重新实现这个接口:

public class MyDerivedClass : MyClass, IMsg
{
public new void Message()
{
Console.WriteLine( "MyDerivedClass" );
}
}

添加的IMsg让你的派生类的行为发生了改变,以至IMsg.Message现在是在派生类上使用的:

MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyDerivedClass"

派生类上还是须要在MyDerivedClass.Message()方法上添加关键字new,这还是有一点隐患(参见原则29)。基类还是可以通过接口引用来访问:

MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyDerivedClass"
MyClass b = d;
b.Message( ); // prints "MyClass"

唯一可以修正这个问题的方法是修改基类,把接口的申明修改为虚函数:

public class MyClass : IMsg
{
public virtual void Message()
{
Console.WriteLine( "MyClass" );
}
}

public class MyDerivedClass : MyClass
{
public override void Message()
{
Console.WriteLine( "MyDerivedClass" );
}
}

MyDerivedClass以及其它所有从MyClass派生的类可以申明它们自己的Message()方法。这个重载的版本每次都会调用:通过MyDerivedClass的引用,通过IMsg接口的引用,或者直接通过MyClass的引用。

如果你不喜欢混杂的虚函数概念,那就对MyClass的定义做一个小的修改:

public abstract class MyClass, IMsg
{
public abstract void Message();
}

回复 使用道具 举报
我只知道接口是定义行为规范的,不会具体的实现,而类是负责功能的具体实现.
类里面有抽象的方法,属性,也可以有具体的方法属性.
一个类只可以继承一个基类也就是父类,但可以实现多个接口.
虚函数在基类中定义,它也是一种成员函数,而且还是非静态成员函数.
回复 使用道具 举报
说实话,这个问题,以前在公司有人跟我争论过,大家意见不一样,

怎么讲呢,一般在大公司里面,都会有专门的架构师,新的一个项目开始了,他们会提前开会讨论采用什么技术?什么语言?什么方案?分几层?采用什么模式?等等各种规范,然后会确定好大概的框架之后,架构师会搭建好解决方案,然后搭建好各个层,并在中间加上很多设计模式,而设计模式里面大部分就是这些接口,抽象类,子类父类,反射等等这些东西的优化集合,各种模式有各种的好处,也适合于不一样的项目。


下面说说我对这些东西的愚见:

首先接口 和 类之间, 他们都是class, 只不过接口是是特殊的class,通常在接口里面会定义很多方法,但是这些方法都只是定义好了,但是不去写具体的方法体(就是不去写方法的具体实现过程的代码),而是在另外一个地方实现这个接口, 这样的话就只需要同意的管理这些个n多的接口,方面了后期的bug修改,系统升级维护等。

类是一个很大的概念,在net里面好像都是在class里面的,这个范围太广,我也说不清楚,就像object是所有的对象的最顶级一样,哈哈,比方不是很恰当,帮助你理解一下。

虚函数 也是一个很抽象的概念,在定义class的时候在前面加上virtual 的关键字,这样,也不需要实现,通常和abstract类在一起使用,(我公司有项目用到过,但是我没插上手,从上班到现在也没弄很清楚,还要努力学习和研究一下这些个玩意)。


呵呵,要是你把这些东西都玩透了,那就是架构师级别的了,当然前提你还要有深厚的技术功底。推荐你看一本书,叫做《24设计模式》,里面都是这些东西,个人感觉这书初学者看有些难度,但是肯定是好书,我也还在慢慢研究当中,一起努力学习吧
回复 使用道具 举报
黄朝辉 黑马帝 2011-11-4 16:49:27
7#
楼主还少了个 多态。。。。
楼主可以看下我的博客!
http://blog.csdn.net/huihuidetiantang/article/details/6926044
回复 使用道具 举报
10642491 黑马帝 2011-11-5 08:13:50
8#
本帖最后由 10642491 于 2011-11-8 18:23 编辑

{:soso_e100:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马