第7章类与对象本章将首先介绍面向对象编程的基本概念,继而介绍面向对象的基本内容,包括类与对象。本章将着重介绍类与对象的概念、类内部的数据成员与函数成员以及这些成员的访问方式。最后介绍静态类、静态成员、部分类和命名空间等。章节内容7.1面向对象编程的基本知识7.2类与对象7.3类的成员7.4部分类7.5类与命名空间7.6小结7.1.1面向对象编程的历史1967年5月20日,挪威奥斯陆计算机中心的Ole-JohanDahl和KristenNygaad为了解决模拟问题,设计了第一个面向对象的程序设计语言Simula,此时就有了类和实例化的概念。70年代,PARC研究所推出了Smalltalk语言,引入了动态对象和继承性思想。Smalltalk语言被认为是第一个真正的面向对象程序语言。到80年代中后期,面向对象的程序设计日益成熟,并被整个计算机界接受和追逐,面向对象的开发问题便出现了。90年代,MicrosoftVisual系列面向对象的程序设计软件逐渐流行,面向对象的编程已经成为无可取代的潮流,并在无数人的努力下,逐渐走向成熟。7.1.2面向对象编程的概念面向对象编程的对象,即系统中用于描述客观事物的一个实体,是构成系统的一个基本单位。面向对象编程中的类,是具有相同数据成员和函数成员的一组对象的集合,它为属于该类的全部对象提供了抽象的描述。面向对象编程的基本内容就是把数据和函数“封装”到编程所必需的“对象”中,程序由一个个能够起到子程序作用的对象(或单元)组合而成7.1.3面向对象编程的基本特点1.封装。面向对象技术中的封装,简单来说就是将代码及其处理的数据绑定在一起,形成一个独立单位,对外实现完整功能,并尽可能隐藏对象的内部细节。2.继承。继承(Inheritance)也称作派生,指的是特殊类的对象自动拥有一般类的全部数据成员与函数成员(构造函数和析构函数除外)。3.多态。多态性(Polymorphism)是指一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。7.2类与对象角色名:性别:出处:地位:门派地位:爱侣:父亲:母亲:张无忌男倚天屠龙记主角明教教主赵敏张翠山殷素素类对象7.2.1类的定义1.语法:[class-modifiers]classidentifier:[class-base]{class-body};2.注意:工程是任何.NETFramework应用程序的基本构造块,可以简单理解为一个EXE或DLL。类的默认修饰符为internal。一个类只能有一个访问修饰符,使用protectedinternal组合时除外。子类的可访问性不能高于父类。7.2.1类的定义修饰符含义特点public公共对该类的访问不限制private私有访问仅限于类本身protected受保护访问仅限于类本身或从包含类派生的类型internal内部访问仅限于当前工程,类的默认修饰符abstract抽象该类不能生成实例sealed密封该类不允许被继承new只嵌套用表明类中隐藏了由基类中继承来的,与基类中同名的类型7.2.2对象语法:RoleZhangWuji=newRole();张无忌男《倚天屠龙记》主角明教教主赵敏张翠山殷素素7.3类的成员类的成员主要有数据成员和函数成员,也可以嵌套其他类型(如其他类、结构、枚举等)。7.3.1成员访问属性修饰符含义特点public公有成员任何代码均可以访问该成员private私有成员仅限类内部的成员才能访问该成员,是默认访问属性protected保护成员所在类和所在类的派生类可以访问internal内部成员程序集内部可以访问usingSystem;classVehicle//定义汽车类{publicintwheels;//公有成员:轮子个数protectedfloatweight;//保护成员:重量publicvoidF(){wheels=4;//正确,允许访问自身成员weight=10;//正确,允许访问自身成员}}7.3.1成员访问属性classtrain//定义火车类{publicintnum;//公有成员:车厢数目privateintpassengers;//私有成员:乘客数privatefloatweight;//私有成员:重量publicvoidF(){num=5;//正确,允许访问自身成员weight=100;//正确,允许访问自身成员Vehiclev1=newVehicle();V1.wheels=4;//正确,允许访问v1的公有成员//v1.weight=6;//错误,不允许访问v1的保护成员}}7.3.1成员访问属性类的数据成员包含字段、常量和事件。1.字段。字段用于表示与对象或类相关联的变量,包括静态字段、实例字段和只读字段。见下例。2.常量。常量与类的关联方式和变量与类的关联方式相同。使用const关键字声明常量,如果它们声明为public,就可以在类的外部访问。见下例。3.事件。事件是类的成员,在类或对象发生某些行为(例如用户的交互操作或者改变了类的某些字段或属性)时,它可以让对象通知调用程序。客户端可以包含所谓“事件处理程序”的代码来响应该事件。有关事件的详细介绍可参见第9章。7.3.2数据成员classGoods{publicdoubleheight;//实例字段publicreadonlydoublewidth=30;//只读字段在声明时赋值publicstaticintcount=0;//静态字段,publicGoods(doubleh,doublew){height=h;width=w;//只读字段在构造函数中赋值count++;}staticvoidMain(string[]args){Goodsy=newGoods(100,200);Console.WriteLine(height={0},width={1},count={2},y.height,y.width,Goods.count);Goodsz=newGoods(300,400);Console.WriteLine(height={0},width={1},count={2},z.height,z.width,Goods.count);//z.width=700;则编译错误。只读字段不能在这里赋值}}7.3.2数据成员—字段例子classVehicle//定义汽车类{publicconststringcountry=China;//共有常量成员publicintwheels;//公有成员:轮子个数protectedfloatweight;//保护成员:重量}7.3.2数据成员—常量例子7.3.3函数成员类的函数成员包括方法、属性、运算符、索引器、构造函数和析构函数。1.方法。方法是表现类或对象行为的成员函数。2.属性。属性用于描述对象的特征或表示对象的状态,提供对类或对象性质的访问。3.运算符。运算符执行的最简单的操作,即+和-4.索引器。索引器允许对象以数组或集合的方式进行索引。5.构造函数和析构函数classTestMethod{intsquare(intx){returnx*x;}doublesquare(doublex){returnx*x;}decimalsquare(decimalx){returnx*x;}staticvoidMain(){TestMethodt=newTestMethod();Console.WriteLine(Thesquareid{0},{1},{2},t.square(10),t.square(12.34),t.square(123.456m));}}7.3.3函数成员—方法例子classWindow{privatedoublewidth=30;publicdoubleWidth{get{returnwidth;}set{width=value;}}staticvoidMain(string[]args){Windowy=newWindow();y.Width=200;Console.WriteLine(Thewidthofwindowis{0},y.Width);}}7.3.3函数成员—属性例子7.3.4构造函数和析构函数1.构造函数构造函数是特殊的成员函数,主要用于为对象分配空间,完成初始化工作。构造函数的名称必须与类名相同。构造函数可以带参数,但没有返回值。构造函数在对象定义时被自动调用。若没有为类定义构造函数,则系统会生成默认的构造函数。构造函数可以被重载,但不可以被继承。7.3.4构造函数和析构函数类型默认值sbyte、byte、short、ushort、int、uint、long、ulong0char'\x0000'float0.0fdouble0.0ddecimal0.0mboolfalse枚举类型0结构类型把所有成员为类型的默认值引用类型空引用null7.3.4构造函数和析构函数classCar{privatestringdescription;privateuintwheels;publicCar(stringdescription,uintwheels){this.description=description;this.wheels=wheels;}publicCar(stringdescription){this.description=description;this.wheels=4;}}7.3.4构造函数和析构函数2.析构函数析构函数也是特殊的成员函数,主要用于释放类实例,它的特殊性表现如下。析构函数的名称与类名相同,但前面加一个“~”符号。析构函数不能带参数,也没有返回值。当撤销对象时,自动调用析构函数,在代码中不能调用析构函数。析构函数不能被继承,也不能被重载。7.3.4构造函数和析构函数classMyClass{~MyClass(){//代码}}7.4静态类和静态成员静态类无需创建实例就能够访问数据和函数,当类中没有依赖对象标识的数据或行为时,就可以使用静态类。静态类在加载包含该类的程序或命名空间时,由.NETFramework公共语言运行库(CLR)自动加载。7.4静态类和静态成员静态类需要注意如下事项:静态类是不能实例化的类,因而静态类类型的变量也就不能使用new关键字创建。静态类不能被继承。静态类默认继承自System.Object根类,不能显式指定任何其他基类。静态类不能有实例构造函数,系统也不会为其提供默认构造函数,但可以包含静态构造函数。静态类不能有任何实例成员,但可以有常量成员。静态类不能实现任何接口,有关接口的介绍可参见第8章。静态类的成员不能有protected或protectedinternal访问修饰符。静态类的成员默认并不是static类型的,必须用static修饰符显式声明成员。7.4静态类和静态成员在类中,声明为static的成员就是静态成员,不需static修饰的成员默认情况下为实例成员。静态成员通常用于表示不随对象状态而变化的数据或计算。但是,一个类成员是否为静态成员,与类本身是否静态无关。classStudent{intSNO;staticintcount;publicStudent(ints){SNO=s;count++;}publicvoiddisplay(){Console.WriteLine(count={0},SNO={1},count,SNO);}}7.4静态类和静态成员classTestStudent{publicstaticvoidMain(){Students1=newStudent(12);s1.display();Students2=newStudent(20);s2.display();}}7.4静态类和静态成员7.5部分类使用部分类定义就是把类的定义放在多个文件中,使用partial关键字,允许把字段、属性、方法和构造函