资源预览内容
第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
第9页 / 共16页
第10页 / 共16页
亲,该文档总共16页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
实验三类与类的封装【实验目的与要求】理解面向对象程序设计的思想和基本概念使用构造函数和析构函数给类写方法给一个类增加属性理解静态方法和实例方法之间的异同掌握方法的重载掌握类索引器的编写方式掌握运算符的重载【实验内容与步骤】类是C#语言实现面向对象程序设计的基础,它是C#封装的基本单元,类把对 象、属性和方法这些类成员封装在一起构成一个有机的整体,即数据机构。在 C#中,类是程序的最核心部分,没有了类,就连简单的C#程序都不能编译。类是可以包含数据成员(常数和字段)、函数成员(方法、属性、事件、 索引器、运算符、实例构造函数、静态构造函数和析构函数)以及嵌套类型的数 据结构。类类型支持继承,继承是派生类可用以扩展和专用化基类的机制。一、类的声明类的声明就是定义一个新类,其格式如下:属性类修饰符class 标识符:基类类体;类声明包含一组可选的属性(C#使程序员可以创造新的说明性信息种 类,称为属性),后跟一组可选的类修饰符(n ew;public;protected;i nternal;private;abstract;sealed ),然后是关键字class和一个命名该类的标识符,接着是一个可选的继承基类,最后是可根 据需要后接一个分号的类体。类的成员类的成员包括由它的类成员声明引入的成员和从直接基类继承的成员 类的成员分为下列几种类别: 常数,表示与类相关联的常数值。 字段,类的变量。方法,实现可由类执行的计算和操作。 属性,定义与读取和写入这些特性相关的命名特性。 事件,定义可由类生成的通知。索引器,允许以与索引数组相同的方式索引类的实例。 运算符,定义可以应用于类的实例的表达式运算符。 实例构造函数,实现初始化类的实例所需要的操作。 析构函数,实现在永久性放弃类的实例之前要执行的操作。 静态构造函数,实现初始化类自身所需要的操作。 类型,表示类的局部类型。可以包含可执行代码的成员被总称为类的函数成员。类的函数成员是该类的方 法、属性、事件、索引器、运算符、实例构造函数、析构函数和静态构造函数。类声明创建新的声明空间, 而由类声明包含的最近的类成员声明将新成员引入到 此声明空间中。下列规则适用于类成员声明:实例构造函数、静态构造函数和析构函数必须具有与最近的封闭类相同的名称。 所有其他成员必须具有与最近封闭类不同的名称。常数、字段、属性、事件或类型的名称必须不同于在同一个类中声明的所有其他 成员的名称。方法的名称必须不同于在同一个类中声明的所有其他非方法的名称。 此外,方法 的签名必须不同于在同一个类中声明的所有其他方法的签名。实例构造函数的签名必须不同于在同一个类中声明的所有其他实例构造函数的 签名。索引器的签名必须不同于在同一个类中声明的所有其他索引器的签名。 运算符的签名必须不同于在同一个类中声明的所有其他运算符的签名。 类的继承成员不是类的声明空间的组成部分。 因此,允许派生类用与继承成员相 同的名称或签名来声明成员(这实质上隐藏了继承成员)。三、构造函数与析构函数 在可以访问一个类的方法、属性或任何其它东西之前, 第一条执行的语句是包 含有相应类的构造函数。 甚至你自己不写一个构造函数, 也会有一个缺省的构造 函数提供给你。class TestClasspublic TestClass(): base() /由编译器提供一个构造函数总是和它的类名相同,但是,它没有声明返回类型。总之,构造函 数总是 public 的,你可以用它们来初始化变量。public TestClass()/ 在这给变量/ 初始化代码等等。如果类仅包含静态成员 (能以类型调用, 而不是以实例调用的成员 ) ,你可以创建 一个 private 的构造函数。private TestClass() 尽管存取修饰符在这一章的后面将要大篇幅地讨论, 但是 private 意味着从类的 外面不可能访问该构造函数。 所以, 它不能被调用, 且没有对象可以自该类定义 被实例化。并不仅限于无参数构造函数你可以传递初始参数来初始化成员。public TestClass(string strName, int nAge) . 作为一个C/C+程序员,你可能习惯于给初始化写一个附加的方法,因为在构造 函数中没有返回值。当然,尽管在 C#中也没有返回值,但你可以引发一个自制 的异常,以从构造函数获得返回值。但是,当你保留引用给宝贵的资源, 应该想到写一个方法来解决: 一个可以被显 式地调用来释放这些资源。 问题是当你可以在析构函数 (以类名的前面加 的方 式命名)中做同样的事情时,为何还要写一个附加的方法 .TestClass()/ 清除你应该写一个附加方法的原因是垃圾收集器, 它在变量超出范围后并不会立即被 调用,而仅当间歇期间或内存条件满足时才被触发。 当你锁住资源的时间长于你 所计划的时间时,它就会发生。因此,提供一个显式的释放方式是一个好主意,它同样能从析构函数中调用public void Release()/ 释放所有宝贵的资源TestClass()Release();调用析构函数中的释放方法并不是必要的总之,垃圾收集会留意释放对象 但没有忘记清除是一种良好的习惯。四、类方法既然对象能正确地初始化和结束,所剩下来的就是往类中增加功能。在 大多数情况下,功能的主要部分在方法中能得到实现。 以往,对于每个程序来 说,所有的工作都在 Main() 方法中实现。这对于功能简单的程序是合适的,因 为仅仅用来学习一些概念。有个更好的方法来组织你的程序,那就是使用方法。 方法是很有用的,因为方法可以让你在不同的单元中分开设计你的逻辑模块。方法的结构格式如下: 属性 修饰符 返回值类型 方法名(参数) 方法体return 表达式 4.1.1 值传递参数 我们在前面的例子中见过的一个参数就是值传递参数。你用一个值传递 参数通过值传递一个变量给一个方 法方法的变量被调用者传递进来的值的一个拷贝初始化。清单 4.1 示范值 传递参数的使用。清单 4.1 通过值传递参数1: using System;2:3: public class SquareSample4: 5: public int CalcSquare(int nSideLength)6: 7: return nSideLength*nSideLength;8: 9: 10:11: class SquareApp12: 13: public static void Main()14: 15: SquareSample sq = new SquareSample();16: Console.WriteLine(sq.CalcSquare(25).ToString(); 17: 18: 因为传递值而不是引用 (地址)给一个变量,所以当调用方法时 (见第 16 行) ,可以使用一个常量表达式 (25) 。4.1.2 引用参数 尽管可以利用值传递参数和返回值建立很多方法,但你一想到要传递值 并原地修改它 ( 也就是在相同的内存位置 ) ,就没有那么好操作了。 这里用引用参 数就很方便。void myMethod(ref int nInOut) 因为传递了一个变量给该方法 ( 不仅仅是它的值 ) ,变量必须被初始化。 否则,编译器会报警。清单 4.2 显示如何用一个引用参数建立一个方法。清单 4.2 通过引用传递参数1: / class SquareSample2: using System;3:4: public class SquareSample5: 6: public void CalcSquare(ref int nOne4All)7: 8: nOne4All *= nOne4All;9: 10: 11:12: class SquareApp13: 14: public static void Main()15: 16: SquareSample sq = new SquareSample();17:18: int nSquaredRef = 20; /一定要初始化19: sq.CalcSquare(ref nSquaredRef);20: Console.WriteLine(nSquaredRef.ToString();21: 22: 正如所看到的, 所有要做的就是给定义和调用都加上 ref 限定符。因为变量通过 引用传递,就可以用它来计算出结果并传回该结果。 但是,在现实的应用程序中, 强烈建议要用两个变量,一个值传递参数和一个引用参数。4.1.3 输出参数传递参数的第三种选择就是把它设作一个输出参数。 正如该名字所暗示, 一个输出参数仅用于从方法传递回一个结果。它和引用参数的另一个区别在于: 调用者不必先初始化变量才调用方法。这显示在清单 4.3 中。清单 4.3 定义一个输出参数1: using System;2:3: public class SquareSample4: 5: public void CalcSquare(int nSideLength, out int nSquared)6: 7: nSquared = nSideLength * nSideLength;8: 9: 10:11: class SquareApp12: 13: public static void Main()14: 15: SquareSample sq = new SquareSample();16:17: int nSquared; /不必初始化18: sq.CalcSquare(15, out nSquared);19: Console.WriteLine(nSquared.ToString();20: 21: 4.1.4 数组参数的传递当方法的参数前带有 params 关键字 , 这就是一个带数组型参数的方法 在方法的参数列表中使用params关键字,可用于表示方法的形参个数不确定,这 样就可以在使用方法的过程中改变传入方法的实参个数 .带有关键字params的数组型参数必须是方法的参数列表中最后一个参 数, 否则会出现编译错误 .数组型参数中的数组必须是一维数组类型 , 如 int,string( 锯齿 型数组 ), 但 int, 二维数组则不能用来作为数组参数 .示例 3:using System; public class ParamTest 定义带数组型参数的方法成员public void para(params int ary) /Console.Write(n 数组中包含 0 个元素: ,ary.Length);for (int t=0;tary.Length;t+)aryt+; / 改变形参数组元素的值Console.Write( “ t0 ” , a ryt); / 打印形参数组元素的值 public static void Main()int m=1,n=2,p=3,q=4;ParamTest app=ne
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号