《第3章 Visual C#面向对象编程基础.ppt》由会员分享,可在线阅读,更多相关《第3章 Visual C#面向对象编程基础.ppt(79页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、3.1 一个一个简单例子(例子(WinForm方式):方式):计算算圆面面积3.2 类和和对象象3.3 方法方法3.4 属性属性3.5 继承和多承和多态L3.1 一个一个简单例子(例子(WinForm方式):方式):计算算圆面面积早期的程序开发使用过程化的设计方法,对于大型应用程序的开发显得力不从心,后续的维护也比较困难。而面向对象编程方式把客观世界中的业务及操作对象转变为计算机中的对象,这样,程序开发者能够以更趋近于人的思维方式来编程。这使得程序更易理解,开发效率大大提高,维护也更容易。下面介绍面向对象编程的基本知识。下面再看WinForm(WindowsForm的缩写,Windows窗体)
2、应用程序,其功能是计算圆的面积。【例EX3_1】设计计算圆的面积的WinForm应用程序。设计步骤如下:1.新建新建WinForm项目项目运行VS2008,执行【文件】【新建】【项目】菜单命令,弹出“新建项目”对话框,在VisualC#的Windows项目类型中选择“Windows应用程序”模板,项目命名为“EX3_1”,如图3.1所示。图3.1 新建WinForm应用程序项目2.WinForm应用程序开发环境应用程序开发环境单击“确定”按钮后,系统新建了一个命名为“EX3_1”的WinForm项目,并在项目中添加了一个窗体“Form1”,WinForm应用程序开发环境如图3.2所示。图3.2
3、 WinForm应用程序开发环境3.添加控件添加控件在工具箱的“所有Windows窗体”中分别拖曳一个Button控件“”、一个TextBox控件“”和一个Label控件“”到窗体“Form1”中。布局各个控件的分布,布局后的窗体如图3.3所示。图3.3布局控件4.设置控件的属性设置控件的属性打开属性窗口,单击属性窗口上面的下拉框,选择“button1”,将“Text”属性设置为“计算”。如图3.4所示。选择“label1”,删除“Text”属性值。选择“Form1”,“Text”设置为“计算圆的面积”。其中“button1”和“label1”是控件的name属性值。图3.4 设置属性5.添加
4、代码添加代码双击Button控件,系统切换到“Form1.cs”代码编辑器窗口,并且添加了button1的Click事件和事件方法“button1_Click”。在此方法中添加代码,代码如下所示。6.执行程序执行程序按【Ctrl+F5】快捷键执行此程序。输入圆的半径“56”,单击“计算”按钮,结果如图3.5所示。如果要调试程序,可以设置断点逐步调试程序。图3.5 计算圆的面积3.2.1 创建类和对象创建类和对象对象是面向对象语言的核心,数据抽象和对象封装是面向对象技术的基本要求,而实现这一切的主要手段和工具就是类。从编程语言的角度讲,类就是一种数据结构,它定义数据和操作这些数据的代码。类是对象
5、的数据抽象,实例化后的类为对象。1.类的声明类的声明要定义一个新的类,首先要声明它。语法形式:属性集信息类修饰符class类名:类基类成员其中:l属性集信息:C#语言提供给程序员的,为程序中定义的各种实体附加一些说明信息,这是C#语言的一个重要特征。l类修饰符:可以是表3.1所列的几种之一或是它们的有效组合,但在类声明中,同一修饰符不允许出现多次。l类基:它定义该类的直接基类和由该类实现的接口。当多于一项时,用逗号“,”分隔。如果没有显式地指定直接基类,那么它的基类隐含为object。例如:classPoint/Point类的访问权限默认为publicintx,y;/类的成员2.类的成员类的成
6、员类的定义包括类头和类体两部分,其中类体用一对大花括号括起来,类体用于定义该类的成员。语法形式:类成员声明类成员由两部分组成,一个是以类成员声明形式引入的类成员,另一个则是直接从它的基类继承而来的成员。类成员声明主要包括:常数声明、字段声明、方法声明、属性声明、事件声明、索引器声明、运算符声明、构造函数声明、析构函数声明、静态构造函数、类型声明等。当字段、方法、属性、事件、运算符和构造函数声明中含有static修饰符时,则表明它们是静态成员,否则就是实例成员。(1)访问修饰符类成员声明中可以使用如表3.2中的5种访问修饰符中的一种。当类成员声明不包含访问修饰符时,默认约定访问修饰符为priva
7、te。(2)常数声明语法形式:属性集信息常数修饰符const类型标识符=常数表达式,其中:l常数修饰符:new、public、protected、internal、private。类型:sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string、枚举类型或引用类型。常数表达式的值类型应与目标类型一致,或者通过隐式转换规则转换成目标类型。例如:classC_const/定义类C_constpublicconstintX=10;/public修饰符constdoublePI=3.14159;/默
8、认访问修饰符,即约定为privateconstdoubleY=0.618+3.14;【例EX3_2】新建一个命名为“EX3_2”的WinForm项目,在此项目中新建一个类并且访问类中的常量显示在窗体中。设计步骤如下:新建WinForm项目并且添加控件按照【例EX3_1】中新建WinForm项目的方法新建一个命名为“EX3_2”项目。从工具箱的“所有Windows窗体”中拖曳一个“Button”控件和一个“Label”控件到窗体上。设置控件以及窗体的属性“Button”控件的“Text”属性设置为“读取PI值”,删除“Label”控件的“Text”属性值,“Form1”的“Text”属性设置为“
9、访问类中常量”。添加代码双击“Button”控件,添加button1的Click事件代码和类Circle代码,代码如下所示:/命名空间以省略号代替namespaceEX3_2publicpartialclassForm1:FormpublicForm1()InitializeComponent();privatevoidbutton1_Click(objectsender,EventArgse)/读取圆周率label1.Text=Circle.PI.ToString();/通过Circle类访问PI常量classCircle/访问权限默认为publicpublicconstdoublePI=3
10、.141592653589793;/public修饰符运行程序按【Ctrl+F5】组合键运行程序,单击“读取PI值”按钮,结果如图3.6所示。图3.6 EX3_2运行的结果(3)字段声明语法形式:属性集信息字段修饰符类型变量声明列表;其中:l变量声明列表:标识符或用逗号“,”分隔的多个标识符,并且变量标识符还可用赋值号“=”设定初始值。例如:classAintx=100,y=200;/声明int类型字段floatsum=1.0f;/声明float类型字段l字段修饰符:new、public、protected、internal、private、static、readonly、volatile。加
11、static修饰的字段是静态字段,不加static修饰的字段是实例字段。加readonly修饰符的字段是只读字段。3.创建类的对象创建类的对象类和对象是紧密结合的,类是对象总体上的定义,而对象是类的具体实现。创建类对象时需要使用关键字new。语法形式:类名对象名=new类名();/类名()是构造函数例如在【例EX3_2】的“button1_Click”方法中创建类Circle的一个对象m:Circlem=newCircle();/创建了一个m对象1.构造函数构造函数(1)实例构造函数的声明语法形式:属性集信息构造函数修饰符标识符(参数列表):base(参数列表):this(参数列表)构造函数语
12、句块其中:l构造函数修饰符:public、protected、internal、private、extern。一般的,构造函数总是public类型的。如果是private类型的,表明类不能被外部类实例化。标识符(参数列表opt):构造函数名,必须与这个类同名,不声明返回类型,并且没有任何返回值。它与返回值类型为void的函数不同。构造函数可以没有参数,也可以有一个或多个。例如:classAintX,Y;/声明int类型字段publicA(intx)/带有一个参数的构造函数X=x;/给字段赋值publicA(intx,inty)/带有两个参数的构造函数X=x;Y=y;【例EX3_3】新建一个命名
13、为“EX3_3”的WinForm项目,在此项目中新建一个类“Circle”并且添加构造函数计算圆的面积。设计步骤如下:新建WinForm项目并且添加控件新建WinForm项目并命名为“EX3_3”。从工具箱中拖曳一个“Button”控件、一个“TextBox”控件和两个“Label”控件到窗体上。设置控件以及窗体的属性“Button”控件的“Text”属性设置为“计算”,删除label2的“Text”属性值,label1的“Text”属性设置为“圆的半径:”,“Form1”的“Text”属性设置为“计算圆的面积”。添加代码双击“Button”控件,添加button1的Click事件代码和类Ci
14、rcle代码,代码如下所示。运行程序按【Ctrl+F5】快捷键运行程序,输入圆的半径,单击“计算”按钮,结果如图3.7所示。图3.7 EX3_3运行的结果(2)静态构造函数的声明语法形式:属性集信息静态构造函数修饰符标识符()静态构造函数体其中:l静态构造函数修饰符:externstatic或者staticextern。如果有extern修饰,则说明这是一个外部静态构造函数,不提供任何实际的实现,所以静态构造函数体仅仅是一个分号。l标识符():是静态构造函数名,必须与这个类同名,静态构造函数不能有参数。l静态构造函数体:静态构造函数的目的是对静态字段的初始化,所以它只能对静态数据成员进行初始化
15、,而不能对非静态数据成员进行初始化。例如:classStudentstaticstringXH,XM,XB;/静态字段,分别为学生的学号,姓名,性别staticintNL;/静态字段表示学生年龄static Student()/静态构造函数,不能有参数/静态构造函数,对类的静态字段初始化 XH=081101;XM=王明;XB=男;NL=21;2.析构函数析构函数一般来说,创建一个对象时需要用构造函数初始化数据,与此相对应释放一个对象时就用析构函数。所以析构函数是用于实现析构类实例所需操作的方法。语法形式:属性集信息extern标识符()析构函数体其中:l标识符:必须与类名相同,但为了区分构造函
16、数,前面需加“”,表明它是析构函数。l析构函数:不能写返回类型,也不能带参数,一个类最多只能有一个析构函数。例如:classAintX;publicA()/不带参数的构造函数X=10;A()/析构函数如果没有显式地声明析构函数,则编译器将自动产生一个默认的析构函数。3.3.1 方法的声明方法的声明方法是按照一定格式组织的一段程序代码,在类中用方法声明的方式来定义。语法形式:属性集信息方法修饰符返回类型方法名(形参表)方法体其中:l方法修饰符如表3.3所示。方法修饰符中public、protected、private、internal、protectedinternal属于访问修饰符,表示访问的
17、级别,默认情况下,方法的访问级别为public。l返回类型:方法可以返回值也可以不返回值。如果返回值,则需要说明返回值的类型,它可以是任何一种C#的数据类型,在方法体内通过return语句将数据交给调用者。如果方法不返回值,则它的返回类型可标为void,默认情况下为void。l方法名:每个方法都有一个名称,一般可以按标识符的起名规则随意给定方法名,不过要记住Main()是为开始执行程序的方法预留的,另外不要使用C#的关键字作为方法名。为了使方法容易理解和记忆,建议方法的命名尽可能地同所要进行的操作联系起来,就是我们通常说的顾名思义。l形参表:由零个或多个用逗号分隔的形式参数组成,形式参数可用属
18、性、参数修饰符、类型等描述。当形参表为空时,外面的圆括号也不能省略。l方法体:用花括号括起的一个语句块。例如,假如有三门课程语文(YW)、英语(YY)、数学(SX),可以在学生类中添加计算学生的这三门课程的平均成绩的方法如下所示:classStudent/构造函数等在这里以省略号代替publicintaverageScore(intYW,intSX,intYY)/声明计算平均成绩的方法inta=(YW+SX+YY)/3;/计算平均成绩并赋值给变量a returna;/返回a值1.值参数值参数在方法声明时不加修饰的形参就是值参数,它表明实参与形参之间按值传递。当这个方法被调用时,编译器为值参数分
19、配存储单元,然后将对应的实参的值复制到形参中。实参可以是变量、常量、表达式,但要求其值的类型必须与形参声明的类型相同或能够被隐式地转化为这种类型。这种传递方式的好处是,在方法中对形参的修改不影响外部的实参,也就是说,数据只能传入方法而不能从方法传出,所以值参数有时也被称为入参数。2.引用参数引用参数如果调用一个方法,期望能够对传递给它的实际变量进行操作,用C#默认的按值传递是不可能实现的。所以C#用ref修饰符来解决此类问题,它告诉编译器,实参与形参的传递方式是引用。引用参数与值参数不同,引用参数并不创建新的存储单元,它与方法调用中的实在参数变量同处一个存储单元。因此,在方法内对形参的修改就是
20、对外部实参变量的修改。3.输出参数输出参数在参数前加out修饰符的被称为输出参数,它与ref参数相似,只有一点除外,就是它只能用于从方法中传出值,而不能从方法调用处接受实参数据。在方法内out参数被认为是未赋过值的,所以在方法结束之前应该对out参数赋值。4.参数数组参数数组一般而言,调用方法时其实参必须与该方法声明的形参在类型和数量上相匹配,但有时候我们更希望灵活一些,能够给方法传递任意个数的参数。比如,在3个数中找最大、最小和在5个数中找最大、最小,或任意多个数中找最大、最小能使用同一个方法。C#提供了传递可变长度参数表的机制,使用params关键字来指定一个可变长的参数表。【例EX3_4
21、】新建一个命名为“EX3_4”的WinForm项目,在此项目中定义一个类“Sort”,在此类中定义4种不同的方法并分别使用“值参数”、“引用参数”、“输出参数”和“参数数组”参数传递形式实现查找最大值。设计步骤如下:(1)新建WinForm项目并添加控件新建WinForm项目并命名为“EX3_4”。从工具箱中拖曳一个“Button”控件、一个“TextBox”控件和一个“Label”控件到窗体上。(2)设置控件以及窗体的属性“Button”控件的“Text”属性设置为“查询”,label1的“Text”属性设置为“单击按钮随机生成0100的3个数”,“Form1”的“Text”属性设置为“不同
22、参数传递方式查询最大值并查询其中最大值”。“TextBox”控件的“Multiline”属性设置为“True”,允许TextBox控件多行显示。(3)添加代码双击“Button”控件,添加button1的Click事件代码和类Sort代码,代码如下所示。(4)运行程序按【Ctrl+F5】组合键运行程序,单击“查询”按钮随机生成3个数存放在数组“array”中,并调用不同的方法查询其中最大的数,结果如图3.8所示。图3.8 EX3_4运行的结果说明:(1)此例和以下例子中,除非有特殊说明,否则不列出命名空间。(2)Random类为随机数生成器,能够产生满足某些随机性统计要求的数字序列的类,其中“
23、Random()”构造函数使用与时间相关的默认种子值,初始化Random类的新实例。Next方法的3种重载方法如表3.4所示。(3)在C#中,可以使用字符串rn表示回车换行符。但推荐使用Environment.NewLine(命名空间为System),Environment是类,NewLine是字符串属性,用于获取当前环境中定义的回车换行符字符串。上例中可以直接用“Environment.NewLine”替换掉“rn”。(4)ToString()方法将相应数据类型的值转换为字符串类型。【例EX3_5】下面是一个简单的商品销售管理器。输入“原库存量”、“产品单价”和“销售量”,计算出“现库存量”
24、和“销售额”。设计步骤如下:1.新建新建WinForm项目并添加控件项目并添加控件新建WinForm项目并命名为“EX3_5”。从工具箱中拖曳2个“Button”控件、3个“TextBox”控件、2个“GroupBox”控件,图标为“”和7个“Label”控件到窗体上。其中3个“Button”控件和label1、label2和label3放在groupBox1中,其余的“Label”控件放在groupBox2中。2.设置控件以及窗体的属性设置控件以及窗体的属性窗体“Form1”的Text属性设置为“简单产品销售管理器”,控件的属性设置如表3.5所示。3.添加代码添加代码分别双击button1和
25、button2,添加button1、button2的Click事件代码和类Sort代码,代码如下所示。4.运行程序运行程序按【Ctrl+F5】组合键运行程序,输入“原库存量”、“产品单价”和“销售量”,单击“计算”按钮计算出现库存量和销售额,结果如图3.9所示。单击“清空”按钮清空窗体中的数据。图3.9 EX3_5运行结果【例EX3_6】设计一个WinForm程序,利用方法的重载计算“圆”、“矩形”和“三角形”的图形的面积。设计步骤如下:1.新建新建WinForm项目并添加控件项目并添加控件新建WinForm项目并命名为“EX3_6”。从工具箱中拖曳2个“Button”控件和1个“TabCon
26、trol”控件,图标为“”。2.设置设置“TabControl”控件控件打开“tabControl1”的属性窗口,选中“TabPages”属性后出现的省略号按钮,图标为“”。在弹出的“TabPage集合编辑器”对话框中单击“添加”按钮添加一个成员“tabPage3”。设置各个成员的“Text”属性,分别为“圆”、“矩形”和“三角形”,如图3.10所示。图3.10TabPage集合编辑器单击“确定”按钮完成编辑。分别单击tabControl1中的各个tabPage,添加控件,所添加的控件如表3.6所示。3.其他控件设置其他控件设置button1的“Text”属性设置为“计算”,button2的“
27、Text”属性设置为“清空”,同时再添加一个“name”属性为“label7”的Label控件,清空其“Text”属性值。Form1的“Text”属性值设置为“图形面积计算器”,设计后的窗体如图3.11所示。图3.11 设计后的窗体4.添加代码添加代码分别双击button1和button2,添加button1、button2的Click事件代码和类CGraph代码,代码如下所示。5.运行程序运行程序按【Ctrl+F5】组合键运行程序,输入圆的半径“5”,单击“计算”按钮,结果如图3.12所示,单击“清空”按钮后再输入圆的半径“5.0”,计算结果如图3.13所示。获得的差异结果是利用了形参类型差
28、异而调用了不同的方法。读者可以试试计算其他图形的面积。这里需要注意的是,在输入三角形边长时,要输入能构成三角形的边长。图3.12 计算低精度圆面积 图3.13 计算高精度圆面积说明:(1)“TabControl”控件用于显示多个选项卡,这些选项卡类似于笔记本中的分隔卡和档案柜文件夹中的标签。选项卡中可包含图片和其他控件。可以使用该选项卡控件来生成多页对话框,此外,TabControl还可以用来创建用于设置一组相关属性的属性页。TabControl的最重要的属性是TabPages,该属性包含单独的选项卡。(2)“Math”类。为三角函数、对数函数和其他通用数学函数提供常数和静态方法。在“Syst
29、em”命名空间中。例中“Math.PI”是获得圆周率,“Math.Sqrt”是计算平方根。(3)字符串类型的“IndexOf”方法。报告String或一个或多个字符在此字符串中的第一个匹配项的索引。常用的两种重载方法如表3.7所示。(4)“string.Empty”表示空字符串。此字段为只读,值为零长度字符串“”。(5)从上例可以看出,方法calculate是计算图形面积,类CGraph中有4个同名的方法calculate,它们或参数个数不一样,或参数类型不一样。在调用calculate方法时,编译器会根据调用时给出的实参个数及类型调用相应的方法。但C#提供了属性(property)这个更好的
30、方法,把字段域和访问它们的方法相结合。对类的用户而言,属性值的读和写与字段域语法相同;对编译器来说,属性值的读和写是通过类中封装的特别方法“get”访问器和“set”访问器实现的。属性的声明方法如下:语法形式:属性集信息属性修饰符类型成员名访问器声明其中:l属性修饰符:与方法修饰符相同,包括new、static、virtual、abstract、override和4种访问修饰符的合法组合,它们遵循相同的规则。l类型:指定该声明所引入的属性的类型。l成员名:指定该属性的名称。l访问器声明:声明属性的访问器,可以是一个get访问器或一个set访问器,或者两个都有。语法形式:get/读访问器/访问器
31、语句块set/写访问器/访问器语句块同时包含get和set访问器的属性是读/写属性,只包含get访问器的属性是只读属性,只包含set访问器的属性是只写属性。【例EX3_7】设计一个可以调节按钮控件大小的WinForm程序。当单击此按钮时,按钮控件按照类“ButtonParameter”提供的默认值来设置属性。设计步骤如下:1.新建新建WinForm项目并添加控件项目并添加控件新建WinForm项目并命名为“EX3_7”。从工具箱中拖曳1个“Button”控件、2个“Label”控件、2个“TextBox”控件和2个“TrackBar”控件,图标为“”到窗体“Form1”中。2.设置属性设置属性
32、2个“TrackBar”控件的“Maximum”设置为“100”,其中“trackBar2”的“Orientation”属性设置为“Vertical”,使控件纵向显示。“label1”和“label2”的“Text”属性分别设置为“宽:”和“高:”,“Form1”的“Text”属性设置为“可变按钮控件”,布局控件如图3.14所示。图3.14设置后的窗体及控件3.添加事件代码及类添加事件代码及类“ButtonParameter”的代码的代码分别双击“trackBar1”、“trackBar2”和“button1”控件,系统添加了“Scroll”和“Click”事件以及“trackBar1_Scr
33、oll”、“trackBar2_Scroll”和“button1_Click”方法,添加代码,代码如下所示。4.运行程序运行程序按【Ctrl+F5】组合键运行此程序。分别拖动滚动块调节button1的大小,如图3.15所示,单击button1,按默认值调整属性,如图3.16所示。图3.15调节button1大小图3.16设为默认值3.5.1 继承继承继承不但可以使用现有类的所有功能,还可以对这些功能进行扩展。继承产生的类称为派生类或子类,而被继承的类则称为基类、超类或父类。客观世界中的许多事物之间往往都具有相同的特征,具有继承的特点。图3.17是采用类的层次图表示各种图形继承关系的例子。图3.
34、17 类的层次结构示例1.继承的实现继承的实现语法形式:属性集信息类修饰符class派生类:基类派生类成员其中:属性集信息、类修饰符的使用参见类的声明。例如:2.base关键字关键字实际上,上例中Circle调用的是父类(Shape)的无参构造函数,而不是有参构造函数,它等同于:publicclassCircle:Shape/定义圆类Circle,从Shape类中派生privatedoubleRadius;publicCircle(stringColor,doubleRadius):base()this.Color=Color;this.Radius=Radius;上例程序中的Circle类也
35、可以改写成:publicclassCircle:ShapeprivatedoubleRadius;publicCircle(stringColor,doubleRadius):base(Color)this.Color=Color;this.Radius=Radius;3.System.Object类类C#所有类都派生于System.Object类。在定义类时如果没有指定派生于哪一个类,系统就默认其派生于Object类。上例中Shape的定义就等同于:publicclassShape:System.Object/TODOSystem.Object类常见的公有方法是:(1)Equals:如果两个
36、对象具有相同值时,方法将返回true。(2)GetHashCode:方法返回对象值的散列码。(3)ToString:通过在派生类中重写该方法,返回一个表示对象状态的字符串。(4)GetType:根据内置对象类型指针获得当前对象的实际类型。【例EX3_8】设计一个计算各种图形面积的WinForm程序。其中各种图形的继承关系如图3.17所示。添加3个窗体分别用于计算“圆”、“矩形”和“正方形”图形面积。所添加的3个窗体都继承于窗体“Form1”,这也体现出继承在窗体中的应用。设计步骤如下:(1)新建WinForm项目并再添加3个窗体新建WinForm项目并命名为“EX3_8”。打开“解决方案资源管
37、理器”右击“EX3_8”“添加”“Windows窗体”,在弹出的“添加新项”对话框中单击“添加按钮”添加Windows窗体(对话框中可以修改窗体名称)。按照此方法分别添加命名为“Form2”、“Form3”和“Form4”的窗体。添加完成后打开“解决方案资源管理器”,如图3.18所示。图3.18解决方案资源管理器在“解决方案资源管理器”中双击“Form2”打开窗体。按【F7】键切换到代码编辑窗口,修改代码,让此窗体继承于“Form1”窗体。代码如下所示。以相同的方法修改“Form3”和“Form4”的代码,也继承于“Form1”。namespaceEX3_8publicpartialclass
38、Form2:Form1/Form2继承于Form1publicForm2()InitializeComponent();(2)设计主窗体“Form1”此窗体是选择要计算的图形。如图3.19所示,如单击“圆”时弹出计算圆的窗体。从工具箱中拖曳1个“GroupBox”和“TreeView”控件到此窗体中,图标为“”,groupBox1的“Text”属性设置为“选择图形”,打开treeView1属性窗口选择“Nodes”属性,单击“”图标,在弹出的“TreeNode编辑器”对话框中分别添加“根节点”和“子节点”,同时设置节点的“Text”属性值,如图3.20所示。Form1的“Text”属性设置为“
39、图形”。双击treeView1,添加代码,代码如下所示。图3.19“Form1”窗体图3.20 添加并编辑节点(3)设计窗体“Form2”此窗体用于计算圆面积,如图3.21所示。打开“Form2”窗体。从工具箱中拖曳2个“GroupBox”、1个“Button”、1个“TextBox”和2个“Label”控件到此窗体中。groupBox1、groupBox2、label1、button1和Form2的“Text”属性分别设置为“输入参数”、“计算”、“半径:”、“计算”和“计算圆面积”。其中、label2是显示计算结果,Text属性设置为空值。图3.21“Form2”窗体双击“计算”按钮,添加
40、代码,代码如下所示:namespaceEX3_8publicpartialclassForm2:Form1publicForm2()InitializeComponent();privatevoidbutton1_Click(objectsender,EventArgse)CircleC=newCircle(Convert.ToDouble(textBox1.Text.Trim();/实例化Circle对象Clabel2.Text=圆的面积:+C.GetArea();(4)设计窗体“Form3”此窗体用于计算矩形面积,如图3.22所示。打开“Form3”窗体。从工具箱中拖曳2个“GroupBo
41、x”、1个“Button”、2个“TextBox”和3个“Label”控件到此窗体中。groupBox1、groupBox2、label1、label2、button1和Form3的“Text”属性分别设置为“输入参数”、“计算”、“长:”、“宽:”、“计算”和“计算矩形面积”。其中、label3是显示计算结果,Text属性设置为空值。图3.22“Form3”窗体双击“计算”按钮,添加代码,代码如下所示:namespaceEX3_8publicpartialclassForm3:Form1publicForm3()InitializeComponent();privatevoidbutton1
42、_Click(objectsender,EventArgse)doublec=Convert.ToDouble(textBox1.Text.Trim();doublek=Convert.ToDouble(textBox2.Text.Trim();RectangularR=newRectangular(c,k);label3.Text=矩形面积:+R.GetArea();(5)设计窗体“Form4”此窗体用于计算正方形面积,如图3.23所示。打开“Form4”窗体。从工具箱中拖曳2个“GroupBox”、1个“Button”、1个“TextBox”和2个“Label”控件到此窗体中。groupB
43、ox1、groupBox2、label1、button1和Form3的“Text”属性分别设置为“输入参数”、“计算”、“长:”、“计算”和“计算正方形面积”。其中、label2是显示计算结果,Text属性设置为空值。图3.23 “Form4”窗体双击“计算”按钮,添加代码,代码如下所示:namespaceEX3_8publicpartialclassForm4:Form1publicForm4()InitializeComponent();privatevoidbutton1_Click(objectsender,EventArgse)/计算SquareS=newSquare(Convert
44、.ToDouble(textBox1.Text.Trim();label2.Text=正方形面积:+S.GetArea();(6)运行程序按【Ctrl+F5】组合键运行程序。选择要计算的图形,输入参数,单击“计算”按钮计算图形面积。说明:(1)“TreeView”控件可以为用户显示节点层次结构,树视图中的各个节点可能包含其他节点,称为“子节点”。可以按展开或折叠的方式显示父节点或包含子节点的节点。通过将树视图的CheckBoxes属性设置为true,还可以显示在节点旁边带有复选框的树视图。然后,通过将节点的Checked属性设置为true或false,可以采用编程方式来选中或清除节点。(2)因
45、为“Form2”、“Form3”和“Form4”窗体都继承于“Form1”,所以在“Form1”中添加的控件和事件在所派生的窗口中都被继承。如在“Form2”中选择“正方形”同样弹出“Form4”窗体。(3)因为类Rectangular中字段Length和Width,修饰符为protected,方法GetArea的修饰符为public,所以它们在派生类Square中都可使用。派生类在继承基类的成员基础上,也可以各自增加功能。1.虚方法的重载虚方法的重载在类的方法前加上关键字virtual,则该方法被称为虚方法。通过对虚方法的重载,实现在程序运行过程中确定调用的方法。需要注意的是,这里所讲的重载
46、与前面所讲的通过参数类型与参数个数的不同实现的重载含义是不同的。例如,在【例EX3-8】中计算圆形的面积使用了方法GetArea,也可以通过虚方法实现。在Shape中增加虚方法:publicvirtualdoubleGetArea()return0.0;在Circle类中对虚方法重载:publicoverridedoubleGetArea()returnSystem.Math.PI*radius*radius;2.抽象类和抽象方法抽象类和抽象方法抽象类是一种特殊的基类,并不与具体的事物相联系。抽象类的定义使用关键字abstract。在图3.17中类的层次结构中,并没有“图形”这种具体的事物,所
47、以将“图形”定义为抽象类,派生了“圆形”和“矩形”这样一些可以产生具体实例化的普通类。需要注意的是,抽象类不能被实例化,它只能作为其他类的基类。将Shape类定义为抽象类:publicabstract classShape/定义抽象类Shape/TODO在抽象类中也可以使用关键字abstract定义抽象方法,要求所有的派生非抽象类都要重载实现抽象方法。引入抽象方法的原因在于,抽象类本身是一种抽象的概念,有的方法并不要求具体的实现,而是留下来让派生类来重载实现。Shape类中计算具体的面积方法本身没什么具体的意义,而只有到了派生类Circle类和Rectangular才可以计算具体的面积。抽象方
48、法的写法:publicabstractdoubleGetArea();/抽象类中定义抽象方法GetArea,计算面积则派生类重载实现为:publicoverridedoubleGetArea()/在派生类中重载抽象方法GetArea,计算面积/TODO3.密封类和密封方法密封类和密封方法抽象类只能作为基类,由其他类继承,不能被实例化。相对应的还有一种不能被其他类继承的类,叫密封类,使用sealed关键字定义。如将Rectangular类定义为密封类:publicsealed classRectangular:Shape/定义密封类Rectangular/TODO这样Rectangular类的派
49、生类Square就不再保留,否则,就会出错。如果类的方法声明包含sealed修饰符,称该方法为密封方法。类的实例方法声明包含sealed修饰符,则必须同时使用override修饰符。使用密封方法可以防止派生类进一步重写该方法。如果将圆形Circle类的GetArea方法定义为密封类,必须先将Shape类的GetArea方法定义为:publicvirtualdoubleGetArea()/TODO然后在Circle类中实现密封方法:publicsealed overridedoubleGetArea()/TODO【例EX3_9】将例【EX3_8】中图形类“Shape”设置为抽象类,圆类“seal
50、ed”设置为密封类,并在类“Shape”中添加图形类型字段“ShapeType”。设计步骤如下:(1)添加“ErrorProvider”控件在【例EX3_8】中并没有对有无输入参数值进行判断,这里在窗体“Form1”中添加“ErrorProvider”控件,图标为“”。在此控件属性窗口中将“Modifiers”属性设置为“Public”。(2)修改类“Shape”、“Circle”、“Rectangular”和“Square”代码修改后的代码如下所示。(3)修改各个窗体的button1的Click事件代码代码如下所示。(4)运行程序按【Ctrl+F5】组合键运行程序。选择“圆”,不输入半径,单