面向对象程序设计基础2.ppt_第1页
面向对象程序设计基础2.ppt_第2页
面向对象程序设计基础2.ppt_第3页
面向对象程序设计基础2.ppt_第4页
面向对象程序设计基础2.ppt_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

第5章 面向对象程序设计基础,5.3 构造函数和析构函数,在实际应用中,方法的定义和调用是很复杂的。在此,将从两个特殊的方法(构造函数和析构函数)入手,对其进行进一步的讨论。 在C#中,构造函数是当类实例化时首先执行的函数。反之,析构函数是当实例(也就是对象)从内存中销毁前最后执行的函数。 这两个函数的执行是无条件的,并且不需要程序手工干预。也就是说,只要定义一个对象或销毁一个对象,不用显式地调用构造函数或析构函数,系统都会自动在创建对象时调用构造函数,而在销毁对象时调用析构函数。,2019/6/1,2,5.3.1 构造函数,有时,我们希望创建一个对象时要为其初始化某些特征,这时就需要用到构造函数。 在C#中,构造函数是特殊的成员函数。 构造函数的特殊性表现在如下几个方面: (1)构造函数的函数名和类的名称一样。 (2)构造函数可以带参数,但没有返回值(也不用void声明)。 (3)构造函数在对象定义时被自动调用。,2019/6/1,3,5.3.1 构造函数,(4)如果没有给类定义构造函数,则编译系统会自动生成一个默认的构造函数。 (5)构造函数可以被重载,但不可以被继承。 (6)构造函数的类型修饰符总是public。如果是private,则表示这个类不能被实例化,这通常用于只含有静态成员的类中。,2019/6/1,4,5.3.1 构造函数,【例5-5】通过构造函数,实现在产生一个学生对象时为其完成起名工作。 using System; namespace Example_Construct public class Student public string strName; /数据成员(学生姓名) public Student(string _strName) /特殊方法成员(构造函数) this.strName = _strName; ,2019/6/1,5,5.3.1 构造函数,class Class1 static void Main(string args) Student s = new Student(“张三“); Console.WriteLine(s.strName); ,2019/6/1,6,5.3.1 构造函数,注意:在Student类中,定义了方法Student(),注意这个方法与Student类同名。这样,每当实例化一个Student对象时,总会执行这个函数。 在构造函数中可以没有参数,也可以有一个或多个参数。这表明构造函数在类的声明中可以有函数名相同,但参数个数不同或者参数不同的多种形式,这就是构造函数重载。 用new关键字创建一个类的对象时,类名后的一对圆括号提供初始化列表,这实际上就是提供给构造函数的参数。系统根据这个初始化列表的参数个数、参数类型和参数顺序调用不同的构造函数。,2019/6/1,7,5.3.1 构造函数,【例5-6】实现Time类的构造函数及其重载。 using System; namespace Example_ConstructOverload class Time public int nHour, nMinute, nSecond; public Time() nHour = nMinute = nSecond = 0; ,2019/6/1,8,5.3.1 构造函数,public Time(int Hour) nHour = Hour; nMinute = nSecond = 0; public Time(int Hour,int Minute) nHour = Hour; nMinute = Minute; nSecond = 0; ,2019/6/1,9,5.3.1 构造函数,public Time(int Hour,int Minute,int Second) nHour = Hour; nMinute = Minute; nSecond = Second; class Test static void Main() Time t1, t2, t3, t4;,2019/6/1,10,5.3.1 构造函数,/对t1,t2,t3,t4分别调用不同的构造函数 t1 = new Time(); t2 = new Time(10); t3 = new Time(10, 30); t4 = new Time(10, 30, 30); Console.WriteLine(“t1的时间为:0时1分钟2秒“, t1.nHour, t1.nMinute, t1.nSecond); Console.WriteLine(“t2的时间为:0时1分钟2秒“, t2.nHour, t2.nMinute, t2.nSecond); Console.WriteLine(“t3的时间为:0时1分钟2秒“, t3.nHour, t3.nMinute, t3.nSecond); Console.WriteLine(“t4的时间为:0时1分钟2秒“, t4.nHour, t4.nMinute, t4.nSecond); ,2019/6/1,11,5.3.1 构造函数,程序运行结果如图5-6所示。 注意:实例对象创建时,根据不同的参数调用相应的构造函数完成初始化。,2019/6/1,12,5.3.2 析构函数,前面,介绍了使用构造函数在实例化对象时自动完成一些初始化工作。 反之,在销毁对象时,有时候也希望能自动做一些 “收尾”任务,例如关闭数据库连接等。C#使用析构函数来完成这个功能。,2019/6/1,13,5.3.2 析构函数,析构函数也是类的特殊的成员函数,它主要用于释放类实例。析构函数的特殊性表现在以下几个方面: (1)析构函数的名字也与类名相同,只是需要在其前面加了一个符号“”。 (2)析构函数不接收任何参数,没有任何返回值,不加访问修饰符。 (3)当撤销对象时,自动调用析构函数。 (4)析构函数不能被继承,也不能被重载。 注意:另外,如果试图声明其他不与类名相同,但是以“”开头的方法,编译器会产生错误。,2019/6/1,14,5.3.2 析构函数,【例5-7】为Student类建立析构函数。 public class Student / / 析构函数 / Student() Console.WriteLine(“Call Destruct Method.“); 当程序使用完一个学生对象后,都会自动调用这个析构函数,输出“Call Destruct Method.”。,2019/6/1,15,5.3.2 析构函数,说明:事实上,一般并不需要使用析构函数,.NET Framework提供了默认的析构函数执行内存清理等工作。如果确定需要在销毁对象前,完成一些特殊的任务,才需要使用自定义的析构函数。,2019/6/1,16,5.4 方法,在前面,对类的方法进行了简单的介绍,也对特殊的类方法构造和析构函数进行了介绍。 在实际应用中,方法的定义和调用要复杂得多。 本节将从输入参数、方法重载等方面,对其进行进一步的讨论。,2019/6/1,17,5.4.1 方法的定义及调用,方法是类中用于执行计算或进行其他操作的函数成员。 1. 方法的定义 方法由方法头和方法体组成,其一般定义的格式为: 访问修饰符 返回值类型 方法名(形式参数列表) 方法体各语句; ,2019/6/1,18,5.4.1 方法的定义及调用,说明: (1)如果省略“方法修饰符”,默认为private,表示该方法为类的私有成员。 (2)“返回值类型”指定该方法返回数据的类型,它可以是任何有效的类型,C#通过方法中的return语句得到返回值。如果方法不需要返回一个值,其返回值类型必须是void。 (3)方法名要求满足C#标识符的命名规则,括号()是方法的标志,不能省略。 (4)“方法参数列表”是逗号分隔的类型、标识符对。这里的参数是形式参数,本质是一个变量,它用来在调用方法时接收传给方法的实际参数的值。如果方法没有参数,那么参数列表为空。,2019/6/1,19,5.4.1 方法的定义及调用,【例5-9】方法的定义。 class Motorcycle public void StartEngine() public void AddGas(int gallons) public int Drive(int miles, int speed) return 0; ,2019/6/1,20,5.4.1 方法的定义及调用,2. 方法的调用 调用对象的方法类似于访问字段。在对象名称之后,依次添加句点、方法名称和括号。参数在括号内列出,并用逗号隔开。 【例5-10】方法的调用。 Motorcycle moto = new Motorcycle(); moto. StartEngine(); moto. AddGas(15); moto. Drive(5,20);,2019/6/1,21,5.4.1 方法的定义及调用,3. 从方法返回 一般来说有两种情况将导致方法返回。 (1) 当遇到方法的结束花括号。 (2)执行到return语句。 有两种形式的return语句:一种用在void方法中(即无需有返回值的方法),另一种用在有返回值的方法中。,2019/6/1,22,5.4.1 方法的定义及调用,【例5-11】通过方法的结束花括号返回。 using System; namespace Method class MyClass public void myMethod() int i; for (i = 0; i 10; i+) if (i % 3 = 0) continue; Console.WriteLine(“0n“, i); ,2019/6/1,23,5.4.1 方法的定义及调用,static void Main() MyClass mycls = new MyClass(); mycls.myMethod(); ,程序的运行结果为: ,2019/6/1,24,5.4.1 方法的定义及调用,【例5-12】通过方法的return语句返回。,else i = i * 3; Console.WriteLine(i); return; static void Main() MyClass mycls = new MyClass(); mycls.myMethod(); ,2019/6/1,25,using System; class MyClass public void myMethod() int i = 8; if (i = 5) i = i * 2; Console.WriteLine(i); return; ,5.4.1 方法的定义及调用,【例5-13】通过方法的return语句返回值。,else i = i * 3; return i; static void Main() MyClass mycls = new MyClass(); Console.WriteLine(mycls.myMethod(); ,2019/6/1,26,using System; namespace Method class MyClass public int myMethod() int i = 8; if (i = 5) i = i * 2; return i; ,【例】完善Student类,并测试。,2019/6/1,27,using System; class Student /数据成员,均为默认private访问控制 string name,no; int age; /构造函数 public Student(string _name, int _age) =_name; this.age=_age; this.no=“; Console.WriteLine(“创建0,今年1岁。“,name,age); /方法成员(长大) public void grow() this.age+; Console.WriteLine(“0长大了1岁!今年是1岁!“,name,age); ,【例】完善Student类,并测试。,2019/6/1,28,/方法成员(入学) public void enroll() if(this.age=18) Console.WriteLine(“0入学了,请输入学号: “, ); this.no=Console.ReadLine(); /方法成员(毕业) public void graduate() if(this.age=22) Console.WriteLine(“0大学毕业。 “,); this.no= “ “; ,【例】完善Student类,并测试。,2019/6/1,29,class Test /测试类 static void Main() /主方法,程序的入口方法 Student s1,s2; s1=new Student(“张三“,16); s2=new Student(“李四“,17); for(int y=2010; y2018; y+) s1.grow(); s2.grow(); s1.enroll(); s2.enroll(); s1.graduate(); s2.graduate(); ,5.4.3 方法的重载,有时,对于类需要完成的同一个功能,要求可能比较复杂。例如,对学生类而言,如果想要使其具有一个“成长”方法,但是这个方法,可能是使学生增加一岁,也可能是增加指定的岁数,该如何解决这个问题呢? C#使用重载技术来完成这个功能。 重载是指允许存在多个同名函数,而这函数的参数不同(或许是参数个数不同,或许参数类型不同,或许两者都不同)。在调用这个方法时,编译器可以按照输入的参数去调用适当的方法。,2019/6/1,30,5.4.3 方法的重载,【例5-18】方法的重载。 using System; namespace MethodOverload / / 学生类 / public class Student /属性 public string strName; /姓名 public int nAge; /年龄,2019/6/1,31,5.4.3 方法的重载,/ / 成长1岁 / public void Grow() this.nAge+; / / 成长_nAgeSpan岁 / public void Grow(int _nAgeSpan) this.nAge += _nAgeSpan; ,2019/6/1,32,5.4.3 方法的重载,/ / Main函数类 / class Class1 static void Main(string args) Student s = new Student(); s.strName = “张三“; s.nAge = 20; s.Grow(); Console.WriteLine(s.nAge); /输出21 s.Grow(2); Console.WriteLine(s.nAge); /输出23 ,2019/6/1,33,5.4.3 方法的重载,程序运行如果如下: 21 23 注意:学生类中实现了两个Grow()方法;前一个Grow()方法,没有任何输入参数,其功能为使学生年龄加1,后一个同名方法Grow(),带有一个参数_nAgeSpan,其功能为使学生年龄加nAgeSpan。在主函数中,分别调用学生类的Grow()方法,并输入不同的参数,从而得到不同的结果。这样,就可以使用同样的方法名,完成功能类似、具体实现不同的任务了。,2019/6/1,34,5.4.2 方法的参数,调用方法时,可以给方法传递一个或多个值。传给方法的值称为实参(argument),在方法内部,接收实参值的变量称为形参(parameter),形参在紧跟着方法名的括号中声明。形参的声明语法与变量的声明语法一样。形参只在方法内部有效,除了将接收实参的值外,它与一般的变量没什么区别。 C#方法的参数类型主要有:值参数、引用参数、输出参数和参数数组。,2019/6/1,35,C# 中方法的参数有四种类型: 值参数,不含任何修饰符; 引用型参数,以 ref 修饰符声明; 输出参数,以 out 修饰符声明; 数组型参数(可变长参数),以 params 修饰符声明。,方法中的参数,在方法声明时不加修饰的形参就是值参数,它表明实参与形参之间按值传递。这种传递方式的好处是,在方法中对形参的修改不影响外部的实参,也就是说,数据只能传入方法而不能从方法传出,所以值参数有时也被称为入参数。,1.值参数,class Test static void Swap(int x, int y) int temp = x ; x = y ; y = temp ; static void Main() int i = 1, j = 2 ; Swap(i, j) ; Console.WriteLine(“i = 0, j = 1“, i, j) ; ,1.值参数举例,如果调用一个方法,期望能够对传递给它的实际变量进行操作,用C#默认的按值传递是不可能实现的。所以C#用ref修饰符来解决此类问题,它告诉编译器,实参与形参的传递方式是引用。 引用与值参数不同,引用参数并不创建新的存储单元,它与方法调用中的实在参数变量同处一个存储单元。因此,在方法内对形参的修改就是对外部实参变量的修改,通常要求在方法外,对引用型参数初始化。,2.引用参数,class Test static void

温馨提示

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

评论

0/150

提交评论