面向对象编程:对象和类型.ppt
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 对象 编程 类型
- 资源描述:
-
按一下以編輯母片標題樣式,按一下以編輯母片,第二層,第三層,第四層,第五層,*,*,*,C#,高级编程:对象和类型,Kavass Zhu,2011/03/22,课程重点,类和结构的区别,字段、属性和方法,按值和引用传递参数,方法重载,构造函数和静态构造函数,只读字段,Object,类,其他类型都从该类派生而来,1.,类和构造,类和结构都是创建对象的模板,每个对象都包含数据和提供处理与访问数据的方法。类定义了每个对象,(,也可以成为实例,),可以包含什么样的数据和功能。例如一个类表示一个顾客,就可以定义字段,CustmoerID,、,FirstName,、,LastName,和,Address,,可以包含该顾客的信息。还可以定义处理存储在这些字段中的数据的功能。接着就可以实例化这个累的对象,以表示某个顾客,并为这个实例设置这些字段,使用其功能,Class PhoneCustomer,public int CustomerID;,public string FirstName;,public string LastName;,public String Address;,结构在内存中的存储方式与类不同,类是存储在堆,(heap),上的引用类型,而结构是存储在栈,(stack),上的值类型、访问方式和一些特征与类也不同,(,如结构不支持继承,),。,较小的数据类型使用结构可以提高性能,。在语法上结构与类相似,主要的区别是使用关键字,struct,代替,class,来声明结构。,struct PheoneCustomerStruct,public int CustomerID;,public string FirstName;,public string LastName;,public string Address;,对于类和结构,都使用关键字,new,来声明实例,这个关键字创建对象并对其进行初始化:,PhoneCustomer myCustomer=new PhoneCustomer();,PhoneCustomerStruct myCustomer2=new PhoneCustomerStruct();,大多数情况下,类要比结构常用的多。,类中的数据和函数称为类的成员。微软的正式术语对数据成员和函数成员进行了区分。类中的成员可以声明为,public,(表示可以在类的外部直接访问他们)、,private,(表示只能在类中的其他代码来访问)和,protected,(表示只能由该成员所在的类和它的派生类访问),2.,类成员,数据成员包含了类的数据,-,字段、常量和事件。数据成员可以是静态,数据,(与整个类相关)或实例数据(与每个实例对象相关)。对于面向对象语言,类成员总是实例成员,除非用,static,进行显示的声明。,在字段是与类相关的变量。前面的例子中已经使用了,PhoneCustomer,类中的字段,一旦实例化,PhoneCustomer,对象,就可以使用语法,Object.FieldName,来访问这些字段:,PhoneCustomer Customer1=new PhoneCustomer();,Customer1.FirstName=“Simon”;,常量与类的关联方式同变量与类的关联方式一样。使用,const,关键字来声明常量。,事件是类的成员,在发生某些行为时,他可以让对象通知程序。客户可以包含成为“事件处理程序,”,的代码来响应该事件,2.1,数据成员,函数成员提供了操作类中的数据的功能,包括方法、属性和构造函数和析构函数、运算符以及索引器,方法是与某个类相关的函数,它可以是实例方法,也可以是静态方法。实例方法处理某个实例,静态方法提供了更一般的功能,不需要实例化一个类。,属性是可以在客户机上访问的函数组,其访问方式与访问类的公共字段类似。,C#,为读写类上的属性提供了专用的语法,所以不必使用那些名称中嵌套有,Get,和,Set,的偷工简减料的方法。因为属性的这种语法不同于一般的函数语法,在客户代码中,虚拟的对象被当做实际的东西。,构造函数是在实例化对象时自动调用的函数。他们必须与所属的类同名,且不能有返回类型。构造函数用于初始化字段的值。,析构函数类似与构造函数,但是在,CLR,检查到不再需要某个对象是调用。他们的名称与类相同,但是前面有一个,符号。,运算符执行的最简单的操作就是,+,和,-,。,C#,允许把已有的运算符用于自己的类。,索引器允许对象以数组或集合的方式进行索引。,2.2,函数成员,正式的,C#,术语实际上并没有区分函数和方法。在这个术语中,“函数成员”不仅包含方法,而且也包含类和结构的一些非数据成员。它包含索引器、运算符、构造函数和析构函数等,甚至还有属性。,方法的声明:,在,C#,中,方法的定义包含方法的修饰符、返回值的类型,然后是方法名、输入参数列表和方法体。如果方法有返回值,,return,语句必须与返回值一起使用,以指定出口点。如果方法没有返回值,就把返回类型指定为,void,,因为不能省略返回类型。如果方法不带参数,方法名后面的圆括号不能省略,此时,return,语句是可选的,当到达右化括号时,方法会自动返回。,方法的调用:,C#,方法的调用分为实例方法和静态方法两中,实例方法必须将类实例化以后才能调用,静态方法可以直接调用。,给方法传递参数:,参数可以通过引用或者值传递给方法。在变量通过引用传递给方法时,,2.2.1,方法,被调用的方法得到的就是这个变量,,所以在方法内部对变量进行任何改变在退出后仍然发挥作用,。,而如果变量是通过值传给方法的,被调用的方法得到的是变量的一个副本,也就是说,在方法退出后,对变量进行的修改回丢失,。,对于复杂的数据类型,按引用传递的效率更高,因为在按值传递时,必须复制大量的数据。,在,C#,中,所有的参数都是通过值来传递的,除非太别说明。,但是在理解引用类型的传递过程是需要注意,因为引用类型的对象只包含对象的引用,他们只给方法传递这个引用,而不是对象本身,,,所以对底层对象的修改会保留下来,。相反值类型的对象包含的是实际数据,所以传递给方法的是数据本身的副本。注意字符串是不同的,因为字符串是不能改变的(如果改变字符串的值,就会创建一个全新的字符串),所以字符串无法显示一般引用类型的行为方式,在方法调用中,对字符串所做的任何改变都不会影响原来的字符串。,ref,参数:,通过值传送变量是默认的,也可以迫使值参数通过引用传递给方法,为此,要使用,ref,关键字。如果把一个参数传递给方法,且这个方法的输入参数,前带有,ref,关键字,则该方法对变量所作的任何改变都会影响原来的值:,Public class,static void,SomeFunction(ref,int,i),i=100;,static void,main(string,args,),int,i=0;,SomeFunction(ref,i);,Console.WriteLine(i.ToString,();,这个程序的最终输出结果为:,100,,因为我们将,SomeFunction,方法的变量声明为按引用传递,所以在方法中对变量的改变,会影响在方法外面对变量的引用,out,关键字:,在,C#,中如果需要从一个函数中输出多个值的话,就需要时使用,out,关键字,,而且传递,out,参数的变量可以不进行初始化,,,编译器使用,out,关键字来初始化,。该变量通过引用传递,所以在从被调用的方法中返回时,方法对该变量进行的任何改变都会保留下来。在待用该方法时,还需要使用,out,关键字:,public class,static void,testFunction(out,int,i),i=100;,static void,main(string,arge,),Int,i;,testFunction(out,i);,Console.WriteLine(i,);,方法的重载:,c#,支持方法的重载,为了重载方法,只需声明同名但参数个数和类型不同的方法即可:,Class Displayer,Void,DisplayResult(string,result),Void,DisplayResult(int,result),方法的重载需要注意:,1.,两个方法不能仅在返回类型上有区别,2.,两个方法不能仅根据参数是声明,ref,还是,out,来区分,属性不太常见,因为他们表示的概念是,C#,从,VB,中提取的,而不是从,C+,、,Java,中提取的。属性的概念是:它是一个方法或一对方法,在客户机代码看来,他们是一个字段。,在,C#,中定义属性,可以使用下面的语法:,Public string,SomeProperty,Get,Return,varName,;,Set,varName,=Value;,2.2.2,属性,get,访问器不带参数,且必须返回属性声明的类型。也不应为,set,访问器指定任何显示的参数,但编译器假定它带一个参数,其类型也与属性相同,并表示为,value,,例如:,class people,private string _name;,public string name,get return _name;,set _name=value;,只读和只写属性:,在属性定义中省略,set,访问器,就可以创建只读属性。同样,在属性定义中省略,get,访问器,就可以创建只写属性。但是这不是好的编程方式。因为这可能为使客户机代码的作者感到迷糊。一般情况下,如果要这么做,最好使用一个方法替代。,属性的访问修饰符:,C#,允许给属性的,get,和,set,访问器设置不同的访问修饰符,所以属性可以有公共的,get,访问器和私有或受保护的,set,访问器。这有助于控制属性的设置方式或时间。在,get,和,set,访问器中,必须有一个具备属性的访问级别。如果,get,访问器的级别是,protected,,就会产生一个编译错误,因为这会使两个访问器的级别都不是属性。不能同时为两个访问器指定访问修饰符。,class people,private string _name;,public string name,protected get return _name;,public set _name=value;,将会,产生一个编译错误,因为在,C#,中不允许同时为属性的两位访问器添加访问修饰符,在,C#,中声明基本构造函数的语法与在,Java,和,C+,中相同。下面声明一个与包含的类同名的方法,但该方法没有返回类型:,Public class,myClass,Public,myClass,(),与,java,和,C+,相同,没有必要给类提供构造函数。一般情况下如果没有提供任何构造函数,编译器会在后台创建一个默认的构造函数。,构造函数的重载遵循与其他方法相同的规则。可以为构造函数提供任意多的重载,只要他们的签名有明显的区别即可:,Public class,myClass,Public,myClass,(),public,myClass(int,number),但是需要注意,如果提供了带参数的构造函数,编译器就不会自动提供默认的构造函数。,2.2.3,构造函数,可以把构造函数定义为,private,或,protected,,这样不相关的类就不能访问他们,这个就不能使用,new,运算符在外部代码中实例化。这在下面两种情况下是有用的:,1.,类仅用作某些静态成员或属性的容器,因此永远不会实例化,2.,希望类仅通过调用某个静态成员函数来实例化,静态构造函数:,C#,的一个新特征是可以给类编写无参数的静态构造函数,这种构造函数只执行一次,而前面我们所说的都是实例构造函数,只要创建类的对象,它都会执行。编写静态构造函数的一个原因是,类的一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。,.net,运行库没有确保静态构造函数什么时候执行,所以不要把代码放在某个特定的时刻执行的静态构造函数中,。也不能预计不同类的静态构造函数按照什么顺序执行。但是可以确保静态构造函数最多运行一次,即在代码引用类之前执行。,静态构造函数没有访问修饰符,其他,C#,代码从来不调用它,但是在加,载类时,总是有,.net,运行库调用它,所以像,public,和,private,这样的访问修饰符就没有意思了。静态构造函数不能带任何参数,,一个类只能有一个静态构造函数,。很显然,,静态构造函数只能访问累的静态成员,不能访问类的实例成员。,无参数的实例构造函数可以在类中与静态构造函数安全共存,尽管参数列表时相同的,但这并不矛盾,因为静,态构造函数是在加载类时执行,而实例构造函数是在创建实例时执行,,所以构造函数的执行不会冲突。,如果多个类都有静态构造函数,先执行哪个静态构造函数是不确定的。此时应该根据其他静态构造函数的执行情况,在静态构造函数中添加代码。如果静态字段有默认值,他们就在调用静态构造函数之前指定。,从其他构造函数中调用构造函数:,有时,在一个类中有几个构造函数,以容纳某些可选参数,这些构造函数都包含一些共同的代码,例如:,class car,Private string,desc,;,Private,uint,wheels;,Public,car(string,desc;uint,wheels),This.desc,=,desc,;,This.wheels,=wheels;,Public,car(string,desc,),This.desc,=,desc,;,This.wheels,=4;,这两个构造函数初始化了相同的字段,显然,最好把所有代码放在一个地方。,C*,有一个特殊的语法,称为构造函数初始化器,可以实现此目的:,class car,Private string,desc,;,Private,uint,wheels;,Public,car(string,desc;uint,wheels),This.desc,=,desc,;,This.wheels,=wheels;,Public,car(string,desc,),:,this(desc,4),这里,,this,关键字仅调用参数最匹配的那个构造函数。注意,构造函数初始化器在构造函数之前执行。,常量的概念就是一个包含不能修改的值的变量,常量是,C#,与大多数编程语言共有的。常量不必满足所有的要求。有时可能需要一些变量,其值不应改变,但在运行前其值是未知的,,C#,为这种情形提供了另一个类型的变量:只读字段。,readonly,关键字比,const,灵活得多,允许把一个字段设置为常量,但是可以执行一些运算,以确定他的初始值。其规则是,可以在构造函数中给只读字段赋值,但是不能再其他地方赋值,只读字段还可以是一个实例字段,而不是静态字段,,类的每个实例可以有不同的值。与,const,字段不同,如果把只读字段设置为静态,就必须显示声明。,还要注意,在构造函数中不必给只读字段赋值,如果没有赋值,他的值就是其数据类型的默认值,或在声明时给他初始化值。,Class,testReadOnly,readonly,string name;,Static,readonly,int,age;,2.3,只读字段,Public,testReadOnly,(),name=“kavass”;,Static,testReadOnly,(),age=0;,前面介绍了类如何封装程序中的对象,也介绍了如何将他们保存在堆中,通过这种方式可以在数据的生存期上获得很大的灵活性,但性能会有一定的损失。因托管堆得优化,这种性能损失比较小。但是,有时仅需要一个小的数据结构,此时类提供的功能多于我们需要的功能,由于性能的原因,最好使用结构。结构的声明如下:,Struct,structName,为结构定义函数和为类定义函数完全相同。在许多方面,可以把,C#,中的结构看做是缩小的类。他们基本上与类相同,,但更适合于把一些数据组合起来的的场合,。他们与类的区别在于:,1.,结构是值类型,类是引用类型。,2.,结构不支持继承。,3.,结构的构造函数的工作方式有一些区别,,尤其是编译器总是提供一个无参数的默认构造函数,这是不允许替换的。,4.,使用结构,可以指定字段如何在内存中布局。,3,结构,虽然结构是值类型,但是在语法上常常可以把他们当作类来处理,例如:,StructName,sn,=new,StructName,();,因为结构是值类型,所以,new,运算符与类和其他引用类型的工作方式不同。对于,New,运算符并不分配堆中的内存,而是调用相应的构造函数,根据传递给他的参数,初始化所有的字段。结构,变量声明实际上是为整个结构分配堆栈中的空间,所以就可以赋值了。,结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。在结构上调用,new,运算符,或给所有的字段分别赋值,结构就可以完全初始化了。当然,如果结构定义为类的成员字段,在初始化包含对象时,该结构会自动初始化为,0,。,结构是值类型,所以会影响性能,但根据使用结构的方式,这种影响可能是正面的,也可能是负面的,。正面的影响是为结构分配内存时,速度非常快,因为他们将内联或保存在堆栈中。在结构超出了作用域被删除时,速度也很快。另一方面,,只要把结构作为参数传递或把一个结构赋给另一个结构,结构的所有内容就被复制,而对于类只复制引用。这样就会有性能损失,根据结构的大小,性能损失也不同。,3.1,结构是值类型,结构不是为继承设计的。不能从一个结构中继承,唯一的例外是结构继承与,System.Object,。因此,结构也可以访问,System.Object,的方法。在结构中,甚至可以重写,System.Object,中的方法。结构的继承链是:每个结构派生于,System.ValueType,,,System.ValueType,派生于,System.Object,。,ValueType,并没有给,Object,添加任何新成员,但是提供了一些更合适机构的执行代码。不能为结构提供其他基类:每个结构都派生于,ValueType,。,3.2,结构和继承,为结构定义构造函数的方式与为类定义构造函数的方式相同,但不允许定义无参数的构造函数。,这看起来似乎没有意义,其原因隐藏在,.net,运行库的执行方式中。下述情况非常少见:,.net,运行库不能调用用户提供的制定无参数构造函数,因此,Microsoft,采用一种非常简单的方式,禁止在,C#,中的结构内使用无参数的构造函数。,默认构造函数把所有的字段都初始化为,0,,且总是隐式的给出,即使提供了其他带参数的构造函数,也是如此。也不能提供字段的初始化值,以此绕过默认构造函数。,3.3,结构的构造函数,partial,关键字允许把类、结构或接口放在对个文件中。一般情况下,一个类存储在单个文件中。但有时,多个开发人员需要访问同一个类,或者某种类型的代码生成器生成了一个类的某部分,所以把类放在多个文件中是有益的。,partial,关键字的用法是:把,partial,放在类、结构或接口的前面。例如:,Partial class,TheBigClass,Public void,MethodOne,(),Partial class,TheBigClass,Public void,MethodTwo,(),4,部分类,编译包含这两个源文件的项目时,会创建一个,TheBigClass,类,它有两个方法,MethodOne,()和,MethodTwo,()。,在嵌套的类型中,只要,partial,关键字位于,class,关键字的前面,就可以嵌套部分类。在把部分类编译到类型中时,会合并属性、,XML,注释、接口、一般类型的参数属性和成员。,如果类只包含静态的方法和属性,该类就可以是静态类。静态类在功能上与使用私有静态构造函数创建的类相同。不能创建静态类的实例。使用,static,关键字,编译器可以检查以后是否给该类添加了实例成员,如果是就产生一个编译错误,。这样可以确保不创建静态类的实例。静态类的语法如下所示:,Static class,staticUtilities,Public static void,HelperMethod,(),静态类的调用不需要进行实例化,使用类型名即可进行该调用:,staticUtilities.HelperMethod,();,5,静态类,前面提到,所有的,.net,类都派生于,System.Object,。实际上,,如果在定义类时没有指定基类,编译器会自动假定这个类派生于,Object,。其重要性在于,除了自己定义的方法和属性外,还可以访问为,Object,定义的许多公共或受保护的成员方法,这些方法可以用于自己定义的所有其他类中。,在,Object,中定义的方法如下表所示:,6 Object,类,ToString,()方法:,Object.ToString,(),声明为虚类型,该方法的实现代码都是为,C#,预定义数据类型重写过的代码,以返回这些类型的正确字符串表示。,Colors,枚举是一个预定义的数据类型,它实际上实现为一个派生于,System.Enum,的结构,而,System.Enum,有一个相当聪明的,ToString,()重写方法,来处理用户定义的所有枚举。,如果不在自己定义的类中重写,ToString,(),该类将只继承,System.Object,执行方式。如果希望,ToString,()返回一个字符串,其中包含类中对象的值信息,就需要重写它,本节课程,我们讨论了如何声明静态和实例字段、属性、方法和构造函数。还讨论了,C#,中新增的、其他语言中的,OOP,模型中没有的新特性:静态构造函数提供了初始化静态字段的方式,利用结构可以定义高性能的数据类型,遵循更严格的特性集,不需要使用托管的堆。我们还阐述了,C#,中的所有类型最终都派生于类,System.Object,,这说明说有的类型都拥有一组基本的方法。,小结,展开阅读全文

咨信网声明:本文档由用户上传并分享,仅供学习交流、研究之用,未经授权,严禁复制、发行、汇编、翻译或网络传播等,侵权必究。
咨信网小贴示:
1、浏览或下载可查看了解,请点击【咨信网告知】。
2、下载文件中如有侵权或不适当内容,将立即纠正。
3、如果因为网速或其他原因下载失败请重新下载,重复下载[60天内]不扣币。
4、开具发票登录电脑端申请,请点击【索取发票】。
咨信网客服组:【微信客服】
1、浏览或下载可查看了解,请点击【咨信网告知】。
2、下载文件中如有侵权或不适当内容,将立即纠正。
3、如果因为网速或其他原因下载失败请重新下载,重复下载[60天内]不扣币。
4、开具发票登录电脑端申请,请点击【索取发票】。
咨信网客服组:【微信客服】


面向对象编程:对象和类型.ppt
















自信AI助手














微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/14742261.html