《第6章-继承与多态性》由会员分享,可在线阅读,更多相关《第6章-继承与多态性(69页珍藏版)》请在金锄头文库上搜索。
1、C# 程序设计,第6章 继承和多态性,目 录,第6章 继承和多态性,本章介绍了面向对象中比较重要的两个概念继承和多态性。重点介绍了继承的基本方法,基类构造函数的调用,继承成员的隐藏,虚方法与方法重写的概念,抽象方法与抽象类的概念,接口的概念等。,6.1 类的继承,类的继承性,指的是在定义类时,不需要重新编写代码,就能够包含另一个类定义的字段、属性、方法等成员,这种在一个类的基础上,建立新的类的过程,叫做继承。被继承的类叫做基类或父类,继承得到的新类叫做派生类或子类。,6.1 类的继承,6.1.1 继承的基本概念 6.1.2 调用基类构造函数 6.1.3 继承成员的隐藏,6.1.1 继承的基本概
2、念,任务6.1 基类与派生类 创建Windows应用程序,定义Person类,并让Student类继承Person类,让Sudent类的实例调用基类方法和自身定义的方法来显示信息,如图6-1所示。,6.1.1 继承的基本概念,任务6.1 任务实施 (一)创建窗体 (1)创建一个“Windows应用程序”项目。 (2)向窗体上添加一个标签框,两个命令按钮,界面布局如图6-2所示,控件属性参数如表6-1所示。,6.1.1 继承的基本概念,任务6.1 任务实施 (二)代码的编写 (1)按F7打开代码视图,在程序代码最后一个右大括号“”的上方,定义基类Person的代码 (2)在Person类的后面,
3、最后一个右大括号的上方,定义学生类Student的代码 (3)在窗体Form1的类中,声明一个Sudent类型的字段: private Student stu; (4)双击Form1窗体,添加窗体载入事件Form_Load事件代码 (5)在设计窗口中的Form1窗体的【显示基本信息】按钮上双击,为【显示基本信息】按钮添加Click单击事件代码 (6)在设计窗口中的Form1窗体的【显示详细信息】按钮上双击,为【显示详细信息】按钮添加Click单击事件代码,6.1.1 继承的基本概念,任务6.1 任务实施 (三)程序的运行 按下F5键运行该应用程序,单击【显示基本信息】,在标签框中显示学生的基本
4、信息(身份证号、姓名、性别),单击【显示详细信息】显示学生的详细新信息(身份证号、姓名、性别、学号、主修专业),如图6-1所示。,6.1.1 继承的基本概念,任务6.1 支撑知识 (一)派生类的声明 声明一个派生类,跟声明一个一般类的格式是一样的,唯一的不同点就是声明时必须使用“:”指定其继承的基类,派生类声明的一般格式为: public class 派生类名称 : 基类名称 类体 public可以省略,类定义的默认访问类型就是公有型。,6.1.1 继承的基本概念,任务6.1 支撑知识 (二)成员的访问 派生类不能继承基类中的构造函数、静态构造函数以及析构函数,其他的基类成员都被派生类继承。但
5、是并不是说所有的基类成员,派生类对象都可以随便访问,这取决于这些成员被声明时的访问修饰符。 public访问该成员不受限制。 protected访问该成员仅限于其所包含于的类或该类的派生类,即派生类可以访问基类中的protected成员。 private访问该成员仅限于其所包含于的类,即派生类不能直接访问基类的private成员。,6.1.1 继承的基本概念,任务6.1 支撑知识 (三)派生类的构造函数 派生类默认的构造函数只是调用基类的无参数构造函数。如果基类中没有可访问的无参数构造函数,则发生编译时错误,所以在Person类中,需要显式声明一个无参数的构造函数: public Person
6、() ,6.1.2 调用基类构造函数,在创建派生类对象时,系统将先调用基类的构造函数,完成基类部分字段的初始化,然后再调用派生类的构造函数,完成派生类自身字段的初始化。 如果派生类中没有声明构造函数,那么系统会给它一个默认构造函数,该默认构造函数完成的功能就是直接调用其基类的无参数构造函数,此时如果基类中没有无参数构造函数,编译就会出错。 要在派生类中直接调用基类的构造函数,可以通过base关键字指定调用的基类构造函数。,6.1.2 调用基类构造函数,任务6.2 为任务6.1的派生类Student创建构造函数 任务6.1中的派生类Student没有构造函数,系统默认调用基类Person中的无参
7、数构造函数,没有初始化任何一个字段,用显式调用基类构造函数的方法来给派生类Student创建构造函数。本任务提供了两种修改方法。,6.1.2 调用基类构造函数,任务6.2 任务实施 (一)创建项目和窗体 (二)代码的编写 (1)法1:打开任务6.1的项目,为Student类添加下构造函数:,6.1.2 调用基类构造函数,任务6.2 任务实施 (二)代码的编写 (2)法2:打开任务6.1的项目,为Student类添加下构造函数:,6.1.2 调用基类构造函数,任务6.2 任务实施 (三)程序的运行 按下F5键运行该应用程序,如图6-1所示。,6.1.2 调用基类构造函数,任务6.2 支撑知识 (
8、三)程序的运行 按下F5键运行该应用程序,如图6-1所示。,6.1.2 调用基类构造函数,任务6.2 支撑知识 (一)向基类构造函数传递参数 派生类显式调用基类构造函数的一般形式如下: public 派生类构造函数名(形参列表):base(向基类构造函数传递的实参列表) “base”是C#关键字,表示调用基类的有参构造函数。传递给基类构造函数的实参列表,通常包含在派生构造函数的“形参列表”中,如: public Student(string myid, string myname, string mygender) : base(myid, myname, mygender) 上述构造函数中,
9、调用基类构造函数的参数,就是传递给Student类构造函数的形参。 public Student(string myid, string myname, string mygender,string mysid,string mymajor) : base(myid, myname, mygender),6.1.2 调用基类构造函数,任务6.2 支撑知识 (二)base关键字 要使用“:base()”调用基类的构造函数,“:base()”必须在派生类构造函数方法头后,在方法体标志“”的前面。 “:base()”不能访问正在创建的实例,如果在“:base()”的参数列表中引用this就会发生编译
10、错误。 当派生类的构造函数方法头后有“:base()”,且自身的方法体中也有代码序列时,则创建对象时,先按指定的参数调用基类特定的构造方法,然后返回执行派生类构造函数中的语句进行派生类字段部分的初始化,6.1.3 继承成员的隐藏,任务6.3 隐藏继承成员 定义一个基类BaseClass,其中包含有两个公有成员字段;定义一个BaseClass的派生类DerivedC1,隐藏BaseClass中的一个成员字段(设置成私有类型);再定义一个DerivedC1的派生类DerivedC2,显示相应的值,运行结果如图6-3所示。,6.1.3 继承成员的隐藏,任务6.3 任务实施 (一)创建项目和窗体 (1
11、)创建一个“Windows应用程序”项目。 (2)在窗体上创建一个标签框label1,将其AutoSize属性设为false,Text属性清空,BorderStyle属性设为Fixed3D,拖放到合适大小;窗体的Text属性设为隐藏继承成员.,6.1.3 继承成员的隐藏,任务6.3 任务实施 (二)代码的编写 (1)按F7打开代码视图,在程序代码最后一个右大括号“”的上方,定义基类BaseClass、派生类DerivedC1以及派生类的派生类DerivedC2代码 (2)在Form1窗体上双击,为窗体的载入事件Form1_Load添加事件处理代码 (三)程序的运行 按下F5键运行该应用程序,如
12、图6-3所示。,6.1.3 继承成员的隐藏,任务6.3 支撑知识 (一)隐藏继承成员 在派生类中声明一个和基类中的成员相同名字的成员,并且声明的时候用上new修饰符,就能够把继承自基类的成员给“隐藏”起来。如类DerivedC1隐藏了继承自基类的x,DerivedC2隐藏了继承得到的y。 (二)访问隐藏成员 在派生类中用完全限定名的方式就可以访问被隐藏的基类成员了,6.2 多态性,一个基类类型变量,不仅可以保存一个基类对象的引用(指向一个基类类型的对象),也可以保存其派生类对象的引用(指向派生类类型的对象)。 多态性是指在程序运行时,基类对象执行一个基类与派生类都具有的同名方法调用时,程序可以
13、根据基类对象类型的不同(基类还是派生类)进行正确的调用。 C#中可以通过多种途径实现多态性,可以用虚方法与方法重写的形式,可以用抽象类与抽象方法的形式。,6.2 多态性,6.2.1 虚方法与方法重写 6.2.2 抽象方法与抽象类,6.2.1 虚方法与方法重写,默认情况,派生类从其基类继承属性和方法。如果继承的方法需要在派生类中有不同的行为,则可以“重写”它,即可以在派生类中定义该属性或方法的新实现。必须分别用virtual关键字与override关键字在基类与派生类中声明同名的方法。 基类中的声明格式: public virtual 方法名(参数列表) 派生类中的声明格式: public ov
14、erride 方法名(参数列表) 其中,基类与派生类中的方法名与参数列表必须完全一致。,6.2.1 虚方法与方法重写,任务6.4 多级继承层次结构 声明长方形类(Rectangle)作为基类,椭圆形类(Ellipse)继承长方形类,圆形类(Circle)继承椭圆形类,每个类中都有自己的Name属性,Area方法(计算面积),ToString方法(描述形状)重写实现,具体运行结果如图6-4所示。,6.2.1 虚方法与方法重写,任务6.4 多级继承层次结构,6.2.1 虚方法与方法重写,任务6.4 任务实施 (一)创建项目和窗体 (1)创建一个“Windows应用程序”项目。 (2)向窗体上添加三
15、个标签框,两个文本框,三个单选按钮,一个命令按钮,界面布局如图6-5所示,控件属性参数如表6-2所示。,6.2.1 虚方法与方法重写,任务6.4 任务实施 (一)创建项目和窗体,6.2.1 虚方法与方法重写,任务6.4 任务实施 (二)代码的编写 (1)按F7打开代码视图,在程序代码最后一个右大括号“”的上方,定义基类Rectangle代码 (2)再定义Rectangle类的派生类Ellipse类代码 (3)定义Ellipse类的派生类Circle类代码 (4)选中radioButton1,点击“属性”窗口中的 事件按钮,双击CheckedChanged项,为“矩形”单选按钮radioButt
16、on1添加CheckedChanged事件代码,6.2.1 虚方法与方法重写,任务6.4 任务实施 (二)代码的编写 (5)为“椭圆”单选按钮radioButton2添加CheckedChanged事件代码 (6)为“圆形”单选按钮radioButton3添加CheckedChanged事件代码 (7)在Form1类中,定义一个计算对象面积的方法AreCal (8)双击【创建对象】按钮,为其添加Click事件代码,6.2.1 虚方法与方法重写,任务6.4 任务实施 (三)程序的运行 按下F5键运行该应用程序,选择要创建的对象类型,并在相应的文本框中输入参数,单击【创建对象】按钮,创建对象,并在标签框中显示对象信息,如图6-4所示。,6.2.1 虚方法与方法重写,任务6.4 支撑知识 (一)重写基方法 用override关键字去“重写”一个方法时,被重写的某个基类中的同名方法,叫做重写方法的基方法。以在ClassA类中重写Method1方法为例,寻找重写基方法的步骤,是通过检查ClassA的各个基类确定的,从