电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

C#高级编程.第4章继

18页
  • 卖家[上传人]:s9****2
  • 文档编号:468736108
  • 上传时间:2023-07-24
  • 文档格式:DOC
  • 文档大小:95.51KB
  • / 18 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 1、第4章 继 承第3章介绍了如何使用C#中的各个类,其重点是如何定义方法、构造函数、属性和单个类(或单个结构)中的其他成员。我们指出,所有的类最终都派生于System.Object类,但并没有说明如何创建继承类的层次结构。继承是本章的主题。我们将讨论C#和.NET Framework如何处理继承。本章的主要内容如下:继承的类型实现继承访问修饰符接口4.1 继承的类型首先介绍C#在继承方面支持和不支持的功能。4.1.1 实现继承和接口继承在面向对象的编程中,有两种截然不同的继承类型:实现继承和接口继承。实现继承:表示一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数。在实现继承中,派生类型的每个函数采用基类型的实现代码,除非在派生类型的定义中指定重写该函数的实现代码。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承是非常有效的。例如第31章讨论的Windows Forms类。第31章也讨论了基类System.Windows.Forms.Control,该类提供了常用Windows控件的非常复杂的实现代码,第31章还讨论了许多其他的类,例如Syst

      2、em. Windows.Forms.TextBox和System.Windows.Forms.ListBox,这两个类派生于Control,并重写了函数,或提供了新的函数,以实现特定类型的控件。接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。例如,某些类型可以指定从接口System.IDisposable(详见第12章)中派生,从而提供一种清理资源的方法Dispose()。由于某种类型清理资源的方式可能与另一种类型的完全不同,所以定义通用的实现代码是没有意义的,此时就适合使用接口继承。接口继承常常被看做提供了一种契约:让类型派生于接口,来保证为客户提供某个功能。在传统上,像C+这样的语言在实现继承方面的功能非常强大。实际上,实现继承是C+编程模型的核心。另一方面,VB6不支持类的任何实现继承,但因其底层的COM基础体系,所以它支持接口继承。在C#中,既有实现继承,也有接口继承。它们没有强弱之分,因为这两种继承都完全内置于语言中,因此很容易为不同的情形选择最好的体系结构。4.1.2 多重继承一些语言如C+支持所

      3、谓的多重继承,即一个类派生于多个类。使用多重继承的优点是有争议的:一方面,毫无疑问,可以使用多重继承编写非常复杂、但很紧凑的代码,如C+ ATL库。另一方面,使用多重实现继承的代码常常很难理解和调试(这也可以从C+ ATL库中看出)。如前所述,使健壮代码的编写容易一些,是开发C#的重要设计目标。因此,C#不支持多重实现继承。而C#又允许类型派生于多个接口。这说明,C#类可以派生于另一个类和任意多个接口。更准确地说,因为System.Object是一个公共的基类,所以每个C#类(除了Object类之外)都有一个基类,还可以有任意多个基接口。4.1.3 结构和类第3章区分了结构(值类型)和类(引用类型)。使用结构的一个限制是结构不支持继承,但每个结构都自动派生于System.ValueType。实际上还应更仔细一些:不能建立结构的类型层次,但结构可以实现接口。换言之,结构并不支持实现继承,但支持接口继承。事实上,定义结构和类可以总结为:结构总是派生于System.ValueType,它们还可以派生于任意多个接口。类总是派生于用户选择的另一个类,它们还可以派生于任意多个接口。4.2 实现继承

      4、如果要声明一个类派生于另一个类,可以使用下面的语法:class MyDerivedClass : MyBaseClass/ functions and data members here注意:这个语法非常类似于C+和Java中的语法,但是,C+程序员习惯于使用公共和私有继承的概念,要注意C#不支持私有继承,因此基类名上没有public或private限定符。支持私有继承会大大增加语言的复杂性,实际上私有继承在C+中也很少使用。如果类(或结构)也派生于接口,则用逗号分隔开基类和接口:public class MyDerivedClass : MyBaseClass, IInterface1, IInterface2/etc.对于结构,语法如下:public struct MyDerivedStruct : IInterface1, IInterface2/etc.如果在类定义中没有指定基类,C#编译器就假定System.Object是基类。因此下面的两段代码生成相同的结果:class MyClass : Object /derives from System.Object/etc. 和c

      5、lass MyClass /derives from System.Object/etc. 第二种形式比较常用,因为它较简单。C#支持object关键字,它用作System.Object类的假名,所以也可以编写下面的代码:class MyClass : object /derives from System.Object/etc. 如果要引用Object类,可以使用object关键字,智能编辑器(如Visual Studio)会识别它,因此便于编辑代码。4.2.1 虚方法把一个基类函数声明为virtual,该函数就可以在派生类中重写了:class MyBaseClasspublic virtual string VirtualMethod()return This method is virtual and defined in MyBaseClass;也可以把属性声明为virtual。对于虚属性或重写属性,语法与非虚属性是相同的,但要在定义中加上关键字virtual,其语法如下所示:public virtual string ForeNameget return foreName;

      6、set foreName = value; private string foreName;为了简单起见,下面的讨论将主要集中于方法,但其规则也适用于属性。C#中虚函数的概念与标准OOP概念相同:可以在派生类中重写虚函数。在调用方法时,会调用对象类型的合适方法。在C#中,函数在默认情况下不是虚拟的,但(除了构造函数以外)可以显式地声明为virtual。这遵循C+的方式,即从性能的角度来看,除非显式指定,否则函数就不是虚拟的。而在Java中,所有的函数都是虚拟的。但C#的语法与C+的语法不同,因为C#要求在派生类的函数重写另一个函数时,要使用override关键字显式声明:class MyDerivedClass : MyBaseClasspublic override string VirtualMethod()return This method is an override defined in MyDerivedClass;方法重写的语法避免了C+中很容易发生的潜在运行错误:当派生类的方法签名无意中与基类版本略有差别时,派生类方法就不能重写基类方法了。在C#中,这会出现一个编译错

      7、误,因为编译器会认为函数已标记为override,但没有重写它的基类方法。成员字段和静态函数都不能声明为virtual,因为这个概念只对类中的实例函数成员有意义。4.2.2 隐藏方法如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有声明为virtual 和 override,派生类方法就会隐藏基类方法。在大多数情况下,是要重写方法,而不是隐藏方法,因为隐藏方法会存在为给定类的实例调用错误方法的危险。但是,如下面的例子所示,C#语法可以确保开发人员在编译时收到这个潜在错误的警告,使隐藏方法更加安全。这也是类库开发人员得到的版本方面的好处。假定有人编写了类HisBaseClass:class HisBaseClass/ various members在将来的某一刻,要编写一个派生类,给HisBaseClass添加某个功能,特别是要添加一个目前基类中没有的方法MyGroovyMethod():class MyDerivedClass: HisBaseClasspublic int MyGroovyMethod()/ some groovy implementationreturn

      8、0;一年后,基类的编写者决定扩展基类的功能。为了保持一致,他也添加了一个名为MyGroovyMethod()的方法,该方法的名称和签名与前面添加的方法相同,但并不完成相同的工作。在使用基类的新方法编译代码时,程序在应该调用哪个方法上就会有潜在的冲突。这在C#中完全合法,但因为我们的MyGroovyMethod()与基类的MyGroovyMethod()不相关,运行这段代码的结果就可能不是我们希望的结果。C#已经为此设计了一种方式,可以很好地处理这种情况。首先,系统会发出警告。在C#中,应使用new关键字声明我们要隐藏一个方法,如下所示:class MyDerivedClass : HisBaseClasspublic new int MyGroovyMethod()/ some groovy implementationreturn 0;但是,我们的MyGroovyMethod()没有声明为new,所以编译器会认为它隐藏了基类的方法,但没有显式声明,因此发出一个警告(这也适用于把MyGroovyMethod()声明为 virtual)。如果愿意,可以给我们的方法重命名。这么做,是最好的

      9、情形,因为这会避免许多冲突。但是,如果觉得重命名方法是不可能的(例如,已经为其他公司把软件发布为一个库,所以无法修改方法的名称),则所有的已有客户机代码仍能正确运行,选择我们的MyGroovyMethod()。这是因为访问这个方法的已有代码必须通过对MyDerivedClass(或进一步派生的类)的引用进行选择。已有的代码不能通过对HisBaseClass的引用访问这个方法,因为在对HisBaseClass的早期版本进行编译时,会产生一个编译错误。这个问题只会发生在将来编写的客户机代码上。C#会发出一个警告,告诉用户在将来的代码中可能会出问题-用户应注意这个警告,不要试图在将来的代码中通过对HisBaseClass的引用调用MyGroovyMethod()方法,但所有已有的代码仍会正常工作。这是比较微妙的,但很好地说明了C#如何处理类的不同版本。4.2.3 调用函数的基类版本C#有一种特殊的语法用于从派生类中调用方法的基类版本:base.()。例如,假定派生类中的一个方法要返回基类的方法返回的值的90%,就可以使用下面的语法:class CustomerAccountpublic virtual decimal CalculatePrice()/ implementationreturn 0.0M; class GoldAccount : CustomerAccountpublic override decimal CalculatePrice

      《C#高级编程.第4章继》由会员s9****2分享,可在线阅读,更多相关《C#高级编程.第4章继》请在金锄头文库上搜索。

      点击阅读更多内容
    最新标签
    监控施工 信息化课堂中的合作学习结业作业七年级语文 发车时刻表 长途客运 入党志愿书填写模板精品 庆祝建党101周年多体裁诗歌朗诵素材汇编10篇唯一微庆祝 智能家居系统本科论文 心得感悟 雁楠中学 20230513224122 2022 公安主题党日 部编版四年级第三单元综合性学习课件 机关事务中心2022年全面依法治区工作总结及来年工作安排 入党积极分子自我推荐 世界水日ppt 关于构建更高水平的全民健身公共服务体系的意见 空气单元分析 哈里德课件 2022年乡村振兴驻村工作计划 空气教材分析 五年级下册科学教材分析 退役军人事务局季度工作总结 集装箱房合同 2021年财务报表 2022年继续教育公需课 2022年公需课 2022年日历每月一张 名词性从句在写作中的应用 局域网技术与局域网组建 施工网格 薪资体系 运维实施方案 硫酸安全技术 柔韧训练 既有居住建筑节能改造技术规程 建筑工地疫情防控 大型工程技术风险 磷酸二氢钾 2022年小学三年级语文下册教学总结例文 少儿美术-小花 2022年环保倡议书模板六篇 2022年监理辞职报告精选 2022年畅想未来记叙文精品 企业信息化建设与管理课程实验指导书范本 草房子读后感-第1篇 小数乘整数教学PPT课件人教版五年级数学上册 2022年教师个人工作计划范本-工作计划 国学小名士经典诵读电视大赛观后感诵读经典传承美德 医疗质量管理制度 2
    关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
    手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
    ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.