对VC#NET面向对象多态性问题研究.docx
- 文档编号:10603542
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:9
- 大小:19.81KB
对VC#NET面向对象多态性问题研究.docx
《对VC#NET面向对象多态性问题研究.docx》由会员分享,可在线阅读,更多相关《对VC#NET面向对象多态性问题研究.docx(9页珍藏版)》请在冰豆网上搜索。
对VC#NET面向对象多态性问题研究
对VC#.NET面向对象多态性问题研究
摘要:
在VC#.net程序设计中,面向对象程序设计难点和重点是对多态性的理解和掌握。
如:
接口与抽象类,类和结构体,覆写与重载等,它们有许多的相同点与不同点,在软件开中如何区别和运用,该文一一作了深究。
关键词:
VC#.NET;面向对象程序;多态性
中图分类号:
TP311文献标识码:
A文章编号:
1009-3044(2011)18-4379-04
OnVC#.NETObject-orientedPolymorphismIssues
WUPing-gui
(ChongqingZhengdaSoftwareInstituteBananDistrict,Chongqing400056,China)
Abstract:
InVC#.netprogramming,object-orientedprogrammingdifficultiesandthefocusisonunderstandingandgraspofpolymorphism.Suchas:
interfacesandabstractclasses,classesandstructures,overridingandoverloading,etc.,theyhavemanysimilaritiesanddifferences,differencesinhowsoftwaredevelopmentanduse,thisonebythebottom.
Keywords:
VC#.NET;object-orientedprogram;polymorphism
1接口和抽象类
1.1接口
接口是一组行为的集合,其中每一种方法都有其名称、参数和返回值。
接口方法不能包含任何实现,CLR允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。
C#中的接口不能包含任何静态成员。
一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法。
代码实现字符串大小写转换,如下:
publicinterfaceconvertChar//声明convertChar为一个接口
{
stringlowerString(stringstr);//将所有的字符转换为小写。
}
publicclassLowerTest:
convertChar//LowerTest从convertChar中去继承
{
publicstringlowerString(stringstr)//实现接口中的方法
{
returnstr.ToLower();
}
}
1.2抽象类
抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。
抽象类不能实例化,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new关键字,也不能被密封。
如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。
另外,实现抽象方法由overriding方法来实现。
其代码如下:
abstractpublicclassPerson
{
protectedstring_perID;//定义字段
publicabstractstring_id{get;set;}//定义属性
publicabstractvoidEad();//定义方法
}
publicclassstudent:
Person//学生类从抽象基类Person中继承
{
publicoverridestring_id
{
get
{
return_perID;
}
set
{
_perID=value;
}
}
publicoverridevoidEad()
{
Console.Write("小张正在午餐");
}
}
1.3相同点与不同点
1.3.1相同点
接口与抽象类都不能被直接实例化,可以通过继承实现其抽象方法。
1.3.2不同点
接口支持多继承;抽象类不能实现多继承;接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员;接口是一组行为规范;抽象类是一个不完全的类,着重族的概念;接口可以用于支持回调;抽象类不能实现回调,因为继承不支持;接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。
接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。
例如,Struct就可以继承接口,而不能继承类。
1.3.3规则与场合
请记住,面向对象思想的一个最重要的原则就是:
面向接口编程。
借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:
面向抽象编程。
抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
接口着重于CAN-DO关系类型,而抽象类则偏重于IS-A式的关系;接口多定义对象的行为;抽象类多定义对象的属性;接口定义可以使用public、protected、internal和private修饰符,但是几乎所有的接口都定义为public,原因就不必多说了。
“接口不变”,是应该考虑的重要因素。
所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。
向接口中添加新成员则会强制要求修改所有派生类,并重新编译,所以版本式的问题最好以抽象类来实现。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
对抽象类不能使用new关键字,也不能被密封,原因是抽象类不能被实例化。
在抽象方法声明中不能使用static或virtual修饰符。
2类与结构
2.1什么是类
class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。
所有的类都最终继承自System.Object类,因此是一种引用类型,也就是说,new一个类的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆中。
2.2什么是结构体
struct(结构体)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体。
所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针。
所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。
2.3相同点与不同点
相同点:
语法类似。
不同点:
class是引用类型,继承自System.Object类;struct是值类型,继承自System.ValueType类,因此不具多态性。
但是注意,System.ValueType是个引用类型。
从职能观点来看,class表现为行为;而struct常用于存储数据。
class支持继承,可以继承自类和接口;而struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承。
class可以声明无参构造函数,可以声明析构函数;而struct只能声明带参数构造函数,且不能声明析构函数。
因此,struct没有自定义的默认无参构造函数,默认无参构造器只是简单地把所有值初始化为它们的0等价值。
实例化时,class要使用new关键字;而struct可以不使用new关键字,如果不以new来实例化struct,则其所有的字段将处于未分配状态,直到所有字段完成初始化,否则引用未赋值的字段会导致编译错误。
class可以实抽象类(abstract),可以声明抽象函数;而struct为抽象,也不能声明抽象函数。
class可以声明protected成员、virtual成员、sealed成员和override成员;而struct不可以,但是值得注意的是,struct可以重载System.Object的3个虚方法,Equals()、ToString()和GetHashTable()。
class的对象复制分为浅拷贝和深拷贝(该主题我们在本系列以后的主题中将重点讲述,本文不作详述),必须经过特别的方法来完成复制;而struct创建的对象复制简单,可以直接以等号连接即可。
class实例由垃圾回收机制来保证内存的回收处理;而struct变量使用完后立即自动解除内存分配。
作为参数传递时,class变量是以按址方式传递;而struct变量是以按值方式传递的。
我们可以简单的理解,class是一个可以动的机器,有行为,有多态,有继承;而struct就是个零件箱,组合了不同结构的零件。
其实,class和struct最本质的区别就在于class是引用类型,内存分配于托管堆;而struct是值类型,内存分配于线程的堆栈上。
由此差异,导致了上述所有的不同点,所以只有深刻的理解内存分配的相关内容,才能更好的驾驭。
本系列将再以后的内容中,将引用类型和值类型做以深入的比较和探讨,敬请关注。
当然正如本文标题描述的一样,使用class基本可以替代struct的任何场合,class后来居上。
虽然在某些方面struct有性能方面的优势,但是在面向对象编程里,基本是class横行的天下。
那么,有人不免会提出,既然class几乎可以完全替代struct来实现所有的功能,那么struct还有存在的必要吗?
答案是,至少在以下情况下,鉴于性能上的考虑,我们应该考虑使用struct来代替class:
实现一个主要用于存储数据的结构时,可以考虑struct。
struct变量占有堆栈的空间,因此只适用于数据量相对小的场合。
结构数组具有更高的效率。
提供某些和非托管代码通信的兼容性。
3覆写和重载
3.1覆写
覆写,又称重写,就是在子类中重复定义父类方法,提供不同实现,存在于有继承关系的父子关系。
当子类重写父类的虚函数后,父类对象就可以根据赋予它的不同子类指针动态的调用子类的方法。
从示例的分析,总结覆写的基本特征包括:
在.NET中只有以virtual和abstract标记的虚方法和抽象方法才能被直接覆写。
覆写以关键字override标记,强调继承关系中对基类方法的重写。
覆写方法要求具有相同的方法签名,包括:
相同的方法名、相同的参数列表和相同的返回值类型。
3.1.1虚方法
虚方法就是以virtual关键字修饰并在一个或多个派生类中实现的方法,子类重写的虚方法则以override关键字标记。
虚方法调用,是在运行时确定根据其调用对象的类型来确定调用适当的覆写方法。
.NET默认是非虚方法,如果一个方法被virtual标记,则不可再被static、abstrcat和override修饰。
3.1.2抽象方法
抽象方法就是以abstract关键字修饰的方法,抽象方法可以看作是没有实现体的虚方法,并且必须在派生类中被覆写,如果一个类包括抽象方法,则该类就是一个抽象类。
因此,抽象方法其实隐含为虚方法,只是在声明和调用语法上有所不同。
abstract和virtual一起使用是错误的。
3.2重载
重载,就是在同一个类中存在多个同名的方法,而这些方法的参数列表和返回值类型不同。
值得注意的是,重载的概念并非面向对象编程的范畴,从编译器角度理解,不同的参数列表、不同的返回值类型,就意味着不同的方法名。
也就是说,方法的地址,在编译期就已经确定,是这一种静态绑定。
从示例中,我们总结重载的基本特征包括:
重载存在于同一个类中。
重载方法要求具有相同的方法名,不同的参数列表,返回值类型可以相同也可以不同。
.NET引入泛型技术,使得相同的参数列表、相同的返回值类型的情况也可以构成重载。
abstractpublicclassGraph//定义一个图形类
{
publicvirtualdoubleArea(doublelength)//定义虚方法
{
returnlength;
}
publicdoubleArea(doublelength,doublewidth)//参数列表不同
{
returnlength*width;
}
publicdoubleArea(stringtype,doublelength,doublewidth)//参数类型不同
{
returnlength*width;
}
publicdoubleArea(doublelength,doublewidth,doubleheight)//参数的个数不同
{
returnlength*width*height;
}
publicabstractdoublearea();//定义的抽象方法
}
publicclasstriangle:
Graph//定义一个三角形类
{
publicoverridedoublearea()//覆写基类抽象方法
{
thrownewNotImplementedException();
}
publicoverridedoubleArea(doublelength)//覆写基类抽象方法
{
returnbase.Area(length);
}
}
3.3覆写和重载比较
如表1所示。
4小结
本文针对程序员在掌握C#语言的过程中,容易混淆的地方按不同点、相同点、使用场景进行区别,认识其优劣得失,帮助读者提高软件开发效率,养成学习开发语言的良好习惯。
参考文献:
[1]吴平贵.VC#.NET数据库应用程序设计[M].大连:
大连理工大学版社,2009.
[2]吴平贵.VC#.NET程序设计实训指导[M].大连:
大连理工大学版社,2010.
[3]WatsonK,NagelC.C#入门经典[M].4版.北京:
清华大学出版社,2008.
注:
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC NET 面向 对象 多态性 问题 研究
![提示](https://static.bdocx.com/images/bang_tan.gif)