电子教案-第5章多态性、继承性、命名空间_第1页
电子教案-第5章多态性、继承性、命名空间_第2页
电子教案-第5章多态性、继承性、命名空间_第3页
电子教案-第5章多态性、继承性、命名空间_第4页
电子教案-第5章多态性、继承性、命名空间_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第5章 继承性、多态性和命名空间 继承性(inheritance)和多态性(polymorphism)是面向对象的重要机制,其提高了软件模块的可复用性和可扩充性。在第4章中已经介绍了面向对象的另一特性继承性。这一章我们将介绍了两种C# 2008中的重要概念抽象类和密封类,它们显示了C#语言的多态性。 C# 2008程序是通过使用名空间来组织的。其不仅可以是应用程序的内部结构体系,同样也可以是外部结构体系。如果程序中的一些元素要被导出到其他程序,可以使用命名空间。程序中免不了会出现错误,这时就会用到C#语言的异常处理机制。5.1 继承机制 面向对象的重要机制之一继承是可以使用以前建造类的方法和属

2、性。通过简单的程序代码来建造功能强大的类,不仅会节省很多编程时间,而且还可以减少代码出错的机会。5.1.1 继承的概念 通过一个实际应用问题,来讲解类的继承这个问题,如代码所示。 【本示例参考:示例代码Chap05NoUseInheritance】 在上面的程序中,定义了Person类和Student类,结果发现Student类包含了Person类的所有属性和方法。在C# 2008语言中,只要表明Student类继承了Person类,就不用在类Student中重复写类Person中的代码了。5.1.2 继承的机制 子类对象中的成员变量的初始化实过程如下: (1)分配成员变量的存储空间,并进行默

3、认的初始化。 (2)绑定构造函数参数,就是把new Person(实际参数列表)中所传递进的参数赋值给构造函数中的形式参数变量。 (3)如果有this()调用,则调用相应的重载构造方法。 (4)显式或隐式追溯调用父类的构造方法。 (5)进行实例变量的显式初始化操作,也就是执行定义成员变量时就进行赋值的语句。 (6)执行当前构造函数体中的代码。5.2 多态性 在面向对象的系统中,多态性允许对一个对象进行操作,由一个对象完成一系列的动作,具体实现哪个动作由系统负责解释。在C# 2008中,多态性的定义是:同一操作作用于不同的类的实例,不同类将进行不同的解释,最后产生不同的执行结果。其支持两种类型的

4、多态性:编译时多态性和运行时多态性。编译时多态性是通过重载来实现的,其根据传递的参数、返回的类型等信息决定实现何种操作。在第4章已经介绍了。运行时多态性是指直到系统运行时,才根据实际情况决定实现何种操作,其是通过虚方法来实现的。5.2.1 虚方法 虚方法是通过在方法声明语句的访问修饰符和返回类型之间放置virtual关键字来实现的。当调用虚方法时,运行将确定调用对象是什么类的实例,并调用适当的覆盖方法,通过override关键字来覆盖。通过一段简单的代码如所示,来说明虚方法跟非虚方法的区别。 【本示例参考:示例代码Chap05Difference】 运行结果: A.F B.F B.G B.G

5、5.2.2 抽象类和抽象方法 抽象方法可以看成是没有方法体的虚方法。其是必须被派生类覆盖的方法。在C# 2008中是通过关键字abstract来实现的。如果类的任何一个方法都是抽象的,则该类也必须声明为抽象的。 抽象类的用途是提供多个派生类可共享的基类的公共定义,并使用abstract关键字定义。先定义一个抽象类: abstract class MyClass 抽象类可以看成是接口和普通类的结合,代码5-6演示了抽象方法的使用。5.2.3 抽象方法 抽象类中可以定义抽象方法,如果一个方法要声明为抽象方法,则方法前加上abstract修饰符即可。抽象方法是一个新的虚方法,它不提供具体的方法实现代

6、码。只能在抽象类中声明抽象方法,对抽象方法,不能使用static或virtual修饰符,而且方法中不能有任何可执行代码,只要给出方法的原型就可以了。抽象类的派生类必须实现所有抽象方法,如代码所示。 【本示例参考:示例代码Chap05AbstractMethod2】5.2.4 密封类和密封方法 与override关键字连用的还有sealed关键字,sealed关键字用来表示密封的意思。在C# 2008中,密封类的作用是限制扩展性和灵活性。先定义一个简单的密封类: sealed class MyClass 当程序中密封了某个类时,其他类是不能继承该类的,如代码所示。 【本示例参考:示例代码Chap

7、05SealedClass1】 5.2.5 方法的隐藏 【本节示例参考:示例代码Chap05HidingMethod】 还有一种方法可以实现在派生类中的覆盖,即new关键字。这种过程叫做方法的隐藏。但是,派生类和非抽象类的基类方法必须有相同的方法。代码演示了如何实现方法的隐藏。 运行结果: Study方法被调用 Person方法被调用 方法隐藏的作用就是可以改变基类的方法。如果一个派生类型被强制向上转换为基类型,基类型的方法将被调用。5.3 类型的转换 第3章讲述了基本数据类型变量的类型转换问题,其实对象类型转换也差不多是一个道理。不过在处理对象之前,有时候还经常对变量的类型进行判断,所以下面

8、从类型的判断开始。5.3.1 is关键字is关键字可以检查对象是否与特定的类型兼容。显然,可以用它来判断对象是否为给定的类型。定义格式为:operand is type在上述定义中,当type是一个类,而operand也是该类型、或继承了该类型、或封箱到该类型中时结果为true;当type是一个接口类型,而operand也是该类型,或者执行该接口的类型结果也为true;当type是一个值类型,而operand也是该类型,或者被拆箱到该类型中时结果也为true。如下面的一个简事例:If (newClass is object)执行相应的操作;else执行相应的操作;5.3.2 转换机制值类型和引

9、用类型的根本区别在于在内存中的存储方式,值类型总是在内存中的栈中存储,而引用类型却是在堆栈中存储。堆栈与栈的区别在于,当定义一个值类型变量时,会在栈中分配适当大小的内存,内存中的这个空间用来存储变量所含的值。引用变量也利用栈,但这时栈包含的知识对另一个内存位置的引用,而不是实际值。这个位置是堆中的一个地址。值类型代表基本数据类型,分为三种简单类型(基本数据类型)、结构(用户定义的值类型)和枚举。而引用类型分为类、接口、数组和委托。在第2章已经介绍了值类型间的显示转换和隐式转换。这一小节中,将介绍引用类型间的转换。代码5-15演示了如何实现子类转化为父类。【本示例参考:示例代码Chap05Tra

10、nsformation1】5.3.3 as关键字 as关键字用于在兼容的引用类型之间执行转换,把一种类型转换为指定的引用类型。与强制转换不同as关键字并不会引发错误。其基本格式为: operand as type 当operand的类型是type类型、operand的类型可以隐式转换为type类型、operand的类型可以封箱到类型type类型时,operand的类型就会被转换为相应type类型,否则operand的类型会被赋予null。代码演示了as关键字的使用。 注意:如果operand的类型可以显示转换为type,则operand的类型的结果就是null。 【本示例参考:示例代码Chap

11、05TestAs】5.3.4 封箱(boxing)和拆箱(unboxing)第2章讨论了值类型间的转换,而上面的小节讨论了引用类型间的转换,同时介绍了两者间的区别。封箱(boxing)和拆箱(unboxing),就是在任何值类型、引用类型和object类型间进行转换。1封箱(boxing)封箱是把值类型转换为System.Object类型,或者转换为由值类型执行的接口类型。当把一个值类型转换一个System.Object类型,也就是创建一个System.Object类型实例并将这个值复制给这个object。2拆箱(unboxing)和封箱转换正好相反,拆箱转换是将一个对象类型显示的转换成一个值

12、类型,或是将一个接口类型显示的转换成一个执行该接口的值类型,这种转换是显示进行的,其语法类似于前面的显示类型转换。拆箱的过程分为两步,首先检查这个对象实例。然后把这个实例的值复制给值类型的变量。5.4 异常处理 C# 2008语言支持错误处理和异常(exception)。异常处理是捕获预期的和突发事件的技术,其目的是在错误发生之前,能够事先预料错误,使程序更可靠。异常定义了程序中遇到的非致命的错误,而不是编译时的语法错误。5.4.1 异常处理基础 异常用来表示在应用程序执行期间执行间的错误,以及其他意外行为。当遇到下列情况时,可能会引发异常: 操作资源不可用。 公共语言运行库遇到意外情况。 自

13、定义抛出异常。 在.NET Framework中,类Exception类表示基类异常,其他异常从其继承而来。该类常用的属性有StackTrace属性,InnerException属性,Message属性,HelpLink属性,Data属性,Source属性和TargetSite属性。5.4.2 异常的捕获理解了异常就可以捕获异常,代码演示了如何实现异常的捕获。【本示例参考:示例代码Chap05TestException】代码异常捕获:TestExceptionusing System;using System.Collections.Generic;using System.Linq;usin

14、g System.Text;namespace TestException class Program static void Main(string args) int myArray = new int4 1, 2, 3, 4 ; /错误的赋值 myArray5 = 5; 5.4.3 throws关键字 在异常处理中,还有一个throws关键字,其作用也非常重要。为了详细的了解该关键字,请从代码开始讲解。 【本节示例参考:示例代码Chap05TestThrows1】 在上述的例子中,假设TestException类和MyException类不是同一个人写的,写TestException类的

15、人,在main方法中调用MyException类的数组时候,如何知道数组会出现异常情况呢?也只有知道了它会发生错误,才能够想到用trycatch语句去处理可能发生的异常。 5.4.4 finally关键字 【本节示例参考:示例代码Chap05TestFinally】。 在trycatch语句后,还可以有一个finally语句,finally语句中的代码块不管异常是否被捕获总是要执行的,代码演示了该关键字的使用。 运行结果: 出现错误了 程序执行完毕5.4.5 异常的使用细节 当使用异常的时候,必须注意: 一个方法被覆盖时,覆盖它的方法必须抛出异常或异常的子类。 如果父类抛出多个异常,那么覆盖方

16、法必须抛出那些异常的一个子集,也就是说,不能抛出新的异常。5.5 命名空间 微软公司为程序开发人远提供了成千上万的类组成类库,如果不对这些类进行分门别类的使用和存放,就会像开发人员不用文件夹去管理众多的文件一样,在使用的时候不仅极度困难和不方便,也极易出现类的命名冲突问题。在C# 2008中是通过引入命令空间机制,提供类的多层类命名空间,来解决上述问题。5.5.1 声明命名空间 【本节示例参考:示例代码Chap05Testnamespace】 命名空间是C#类、接口、委托、枚举和其他类型的一个逻辑上的组合。其不仅在使用上灵活了很多,而且还解决了类型之间的命名冲突。命名空间是一种逻辑组合,而不是

17、物理组合。其声明的基本格式: namespace qualified-identifier namespace-body ; 在上述声明中,命名空间使用的关键字“namespace”,其后跟名字空间名和名字空间主体,还必须跟分号。5.5.2 导入命名空间 有了命令空间的基本知识,那么在不同命令空间中的类是如何调用的了,请看代码,【本示例参考:示例代码Chap05Testnamespace2】。 当编译上述代码时,会出现错误。原因在于:在Testnamespace类中,直接调用了Test类。编译器认为两个类在同一个命令空间中,即类Test的完整名被认为是Chap05.Test,所以找不到类Test。只要把“new Test().WriteInfo();”这一句改为“new Chap05.SonPath.Test().WriteInfo();”就可以通过编译了。5.5.3 使用指示符 【本节示例参考:示例代码Chap05】 使用指示符的目的是为了方便使用其他的命名空间中定义的命名空间和类型。其有两种类型:别名使用指示符和命名空间使用指示符。命名空间使用指示符在上一小节已经介绍。 别名使用指示符定

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论