《Net面向对象程序设计-7-创建并管理类和对象.ppt》由会员分享,可在线阅读,更多相关《Net面向对象程序设计-7-创建并管理类和对象.ppt(69页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1孙月江孙月江12第第7章章 创建并管理建并管理类和和对象象定义一个类,在其中包含一些列相互关联的方法和数据项使用public和private关键字,控制成员的可访问性使用new关键字来创建对象并调用一个构造器来初始化自己编写并调用构造器使用static关键字创建可由同一个类的所有实例共享的方法和数据解释如何创建匿名类37.1 理解分理解分类设计一个类的过程,就是对信息进行分类,将相关信息放到一个有意义的实体中的过程47.2 封装的目的封装的目的封装是类的一个重要原则中心思想:使用一个类的程序不应该关系类的内部实际如何工作封装有时也称为信息隐藏封装的目的:将方法和数据合并到一个类中;换言之,为
2、了支持分类控制对方法和数据的访问;换言之,为了控制类的使用类类 和和 对对 象象 类类是是是是对对象的模板,它定象的模板,它定象的模板,它定象的模板,它定义义了了了了对对象的公共属性和行象的公共属性和行象的公共属性和行象的公共属性和行为为(方法)。(方法)。(方法)。(方法)。属性和方法共同称作属性和方法共同称作属性和方法共同称作属性和方法共同称作类类的成的成的成的成员员 对对象是象是象是象是类类的的的的实实例,是具体的例,是具体的例,是具体的例,是具体的 对对象必象必象必象必须须使用使用使用使用 new new 进进行行行行实实例化才可以使用例化才可以使用例化才可以使用例化才可以使用类类 和
3、和 对对 象象 3.1.1 类类 对象对象人类人类 (模板)(模板)阿土仔(具体化)阿土仔(具体化)姓名姓名 姓名姓名 =阿土仔阿土仔性别性别 性别性别 =男男使用卡片(使用卡片()使用使用“陷害卡陷害卡”使用道具(使用道具()使用使用“飞弹飞弹”属性属性方法方法类类 和和 对对 象象 3.1.1 类:类:类:类:相对对象而言,类似于模板或相对对象而言,类似于模板或相对对象而言,类似于模板或相对对象而言,类似于模板或蓝图蓝图蓝图蓝图 包含方法和数据包含方法和数据包含方法和数据包含方法和数据 对象:对象:对象:对象:是类的实例是类的实例是类的实例是类的实例 使用关键字使用关键字使用关键字使用关键
4、字 new new 创建创建创建创建 对象具有状态和行为对象具有状态和行为对象具有状态和行为对象具有状态和行为对象对象厨房厨房起居室起居室浴室浴室书房书房饭厅饭厅储藏室储藏室门廊门廊类类8类概概览Class_definition:=class :=:=:=:=:=:=:=:=:=:=:=:=:=:=:=类成员被分成了三大类类成员被分成了三大类:数据成员数据成员函数成员函数成员嵌套类型嵌套类型9数据成数据成员包括:包括:成员变量:(也叫域)用于表示数据成员变量可以用于类的特定实例(对象)-实例变量;也可以属于类自身(通过声明为static),这时,它称为静态变量或类变量。一个静态方法通过它的类(
5、不是它的对象)来调用且它属于类而不属于对象。同样,一个静态变量属于类而不是任何特定的对象。常量成员变量也可以声明为只读(通过Readonly关键字)常量成员的值在编译程序时被设置为源代码中指定的值,并且在所编译程序的整个生存期内均表示这一值。而只读成员变量在创建时给它赋值,并且在此对象生存期内保持此值。事件按声明成员变量的相似方式来声明。用法大不一样。事件驱动程序。程序执行的下一个动作取决于程序中触发的下一个事件。所以,让程序按语句书写顺序依次执行的思想恐怕得不到实现了。当运行一个GUI应用程序时就需要此异步功能。10函数成函数成员包括:包括:方法构造函数析构函数属性索引器操作符11嵌套嵌套类
6、型:型:类体中定义的类、结构、枚举和接口7.4 控制可控制可访问性性一个方法或字段假如只允许从类的内部访问,就说他是私有的(private)该关键字是默认的,但作为一种良好的编程习惯,应该显式地将方法和字段声明为private一个方法或字段假如既能从类的内部访问,也能从外部访问,就说他是公共的(public)注意:方法中声明的变量默认是不初始化的相反,类中的字段自动初始化为0,false或null作为一个良好的编程习惯,应该显式地初始化字段12命名和可命名和可访问性性.NET Framework推荐以下字段和方法的命名约定,它们是以可访问性为出发点来考虑的:public的的标识符符应该以大写字
7、母开以大写字母开头,例如:,例如:Area非非public的的标识符符应该以小写字母开以小写字母开头,例如:,例如:radius例外:类名是以大写字母开头,而构造器必须完全和类名相同,故一个private的构造器也应该以大写字母开头13147.4.1使用构造器使用构造器字段的构造器创建一个对象时,对应的表示实例变量的内存被分配,这是对象创建过程的一部分。但分配完成后(且在任何自动或人工初始化发生前),内存和实例变量仅表示上次使用后残留的垃圾。将这部分垃圾用于计算就会导致错误的结果。例:distance=time*speed;没有实例化的实例变量很容易导致错误的发生151、自动初始化short、
8、int、float、decimal等为0char类型值赋值为Unicode字符、u0000bool类型值初始为false引用类型初始化为null一般情况下,不推荐让运行时自动执行实例变量的初始化:阅读源代码的程序员不能看到此初始值。他或她可能不知道前面所列的缺省初始值,缺省值随编译器的不同、同一软件公司发行编译器版本的不同而有所差异。162、在声明中给实例变量赋值class Account private decimal balance=100;.private decimal balance=;17如果我们需要一个if语句来确定恰当的初始化值,例如:一个银行可能通过“如果在2004年6月1日
9、前新开帐户,免费赠送开户额200元;如果在6月1日和7月1日期间新开帐户,则赠送开户额100元,7月1日后免费赠额为0,敬请把握良机”来近行特别宣传。18 以上代码看似正确,但实际是无效的。C#只允许if语句及类似语句位于函数成员体的内部。class Account private decimal balance;public void Initialize()if(OpeningDate is earlier than 1st of June)balance=200;else if(OpeningDate is in between 1st of June and 1st of July)b
10、alance=100;else balance=0;19Account myAccount=new Account();myAccount.Initialize();20使用使用实例构造函数例构造函数 类的实例构造函数是一个有专门作用的方法,当用new关键字创建此类的一个对象时调用它。实例构造函数用于执行实例变量的初始化及其他创建对象所需的动作。定义实例构造函数21Instance_Constructor_Definition:=Constructor_Identifier()其中:=private :=public :=protected :=internal:=:base():=:this
11、():=:=;22 ,必须等同于构造函数所在的类标识符。例如一个叫Dog的类中的构造函数必须也叫Dog。实例构造函数不能返回值。所以,没有指定返回类型,甚至也没有使用void关键字。导致执行此实例构造函数前的另一个实例构造函数。23说明:说明:与常规方法一样,实例构造函数定义的构造函与常规方法一样,实例构造函数定义的构造函数标示符后必须用一个圆括号来包含可选的形数标示符后必须用一个圆括号来包含可选的形式参数列表。当用式参数列表。当用new关键字创建一个新对象关键字创建一个新对象时,参数值被传递给这些形式参数。时,参数值被传递给这些形式参数。如果类包含两个或更多的实例构造函数,在声如果类包含两个
12、或更多的实例构造函数,在声明实例构造函数语句之前,你可以选择性地执明实例构造函数语句之前,你可以选择性地执行同一个类中的实例构造函数。通过将构造函行同一个类中的实例构造函数。通过将构造函数初始化器数初始化器this放在形式参数列表后面来实现。放在形式参数列表后面来实现。24调用实例构造函数Cat myCat=new Cat();圆括号看似没有必要,那为什么非要包含它呢?我们已经知道,new cat()创建一个Cat类的新对象并返问一个对此对象的引用在这里,就是将它赋值给myCat。任何方法调用必在方法名后面加一对圆扩号按同样方法调用一个实例构造函数。25类名(在这里就是Cat)后的圆括号可以像
13、常规方法样包括一个参数列表():此参数列表必须与实例构造函数中对应的形式参数列表匹配。如果存在两个或更多个实例构造函数(通常为重载),形式参数列表与传递的参数列表匹配的实例构造函数被执行。26一个带空形式参数列表的实例构造函数称作缺省缺省实例例构造函数构造函数。缺省实例构造函数的另一个术语是无参数实例构造函数。class Tree private int age=0;.class Tree private int age=0;public Tree();.27注意:如果你编写一个或多个非缺省实例构造函数,需要的话,你必须编写自己的缺省实例构造函数:如果你在类中包含一个或多个实例构造函数,C#编
14、译器不会包含一个缺省实例构造函数。例如:class Car private int odometer;public Car(int initialOdometer)odometer=initialOdometer;Car yourCar=new Car();/Invalid.Default 28技巧:如果你在如果你在类中包含一个或多个中包含一个或多个实例构造函数,最好同例构造函数,最好同时包含一个缺省包含一个缺省实例构造函数例构造函数即使你认为类在编写时并不需要一个缺省构造函数,但此类在频繁使用过程中,目的和场合稍有不同时,可能突然需要调用缺省构造函数,当你在构建类时添加缺省实例构造函数就省事
15、了。29重重载实例构造函数例构造函数为了区分重载实例构造函数中包含的不同形式参数列表,像对待常规重载方法一样,编译器遵循相同的判断过程。30构造函数初始化器构造函数初始化器假设无论调用哪一个重载实例构造函数,某个类都需要执行一套核心初始化语句。我们可以首先在每个实例构造函数中包含相同的初始化语句集,然后我们在顶端添加此实例构造函数特定的语句。这样虽然能正常工作,但每个实例构造函数都将承担相同的核心语句执行任务,而且你也要重复复制和粘贴这些语句。另一种办法是,仅在缺省实例构造函数中放入核心语句,并让每个重载实例构造函数通过构造函数初始化器来调用它,这样就可以删除第一种途径中多余的代码了。3101
16、:class Account02:03:private decimal balance;04:private decimal interestRate;05:private string holderName;06:07:public Account(decimal initialBalance,decimal initialInterestRate,08:string initialHolderName)09:10:balance=initialBalance;11:interestRate=initialInterestRate;12:holderName=initialHolderNam
17、e;13:BankStatistician.AccountAdded(balance);14:Console.WriteLine(New account opened);15:16:17:public Account(string initialHolderName):this(0,0,initialHolderName)18:19:Console.WriteLine(Note:Only initial holder name supplied);20:21:22:public Account():this(0,0,Not assigned yet)23:24:Console.WriteLin
18、e(Note:No initial information supplied);25:32私有私有实例构造函数例构造函数private代替public一个私有实例构造函数不能由此类的外部任何地方调用,这与私有方法和私有实例变量相似。一个私有一个私有实例构造函数不能用于例构造函数不能用于创建建对象象,所以只包含私有实例构造函数的类可有效防止防止从此类的外部对类中的任何对象进行实例化。这一原理通常用于一原理通常用于仅包含静包含静态成成员的的类中中。这些静态类根本没有必要实例化,这样可阻止在程序的其他部分对他们的偶然实例化。分部分部类一个类可能包含大量方法、字段、构造器以及其他内容一个功能齐全的类可
19、能相当大C#中,可以将一个类的源代码拆分到单独的文件中这样一来,大型类就可以使用较小的、更容易管理的部分来进行组织使用partial关键字来定义类的不同部分34partial class Circlepublic Circle()/default constructorthis.radius=0;public Circle(int initialRadius)/overloaded constructorthis.radius=initialRadius;The contents of circ2.cs look like this:partial class Circleprivate in
20、t radius;public double Area()return Math.PI*this.radius*this.radius;40静静态成成员变量量实例例变量表示与量表示与单个个对象相关的数据,当象相关的数据,当创建一个建一个对象象时,它的,它的实例例变量量赋于于对应于此于此对象的象的值,而且,而且这些些值在在对象的生存期象的生存期间与与对象保持一致。象保持一致。如果我如果我们要表示属于同一要表示属于同一类的整的整组对象相关的信象相关的信息片断息片断?注意:静态成员变量也叫做共享字段,共享字段,类似于全局似于全局变量量一个静态成员变量使用类名加点操作符不能通过对单个对象使用点操作符来
21、访问。4101:using System;02:using System.Collections;03:04:class Account05:06:public static uint totalAccountsCreated=0;07:08:public Account()09:10:totalAccountsCreated+;11:12:13:14:class Bank15:16:private ArrayList accounts;17:18:public Bank()19:20:Console.WriteLine(Congratulations!You have created a n
22、ew bank);21:accounts=new ArrayList();22:23:4224:public void AddNewAccount()25:26:accounts.Add(new Account();27:Console.WriteLine(New account added!);28:PrintStatistics();29:30:31:public void RemoveFirstAccount()32:33:if(accounts.Count 0)34:35:accounts.RemoveAt(0);36:Console.WriteLine(Account removed
23、!n);37:PrintStatistics();38:39:else40:41:Console.WriteLine(Sorry no more current accounts);42:43:44:45:public void PrintStatistics()46:47:Console.WriteLine(Number of current accounts:+accounts.Count+48:nNumber of new accounts created:+Account.totalAccountsCreated);49:50:4352:class DynamicBankSimulat
24、ion53:54:private static Bank bigBucksBank;56:public static void Main()57:58:string command;60:bigBucksBank=new Bank();61:do62:63:PrintMenu();64:command=Console.ReadLine().ToUpper();65:switch(command)66:67:case A:68:bigBucksBank.AddNewAccount();break;70:case E:71:Console.WriteLine(Bye Bye!);break;73:
25、case R:74:bigBucksBank.RemoveFirstAccount();break;76:case P:77:bigBucksBank.PrintStatistics();break;79:default:80:Console.WriteLine(Invalid choice);81:break;82:83:while(command!=E);84:4486:private static void PrintMenu()87:88:Console.WriteLine(nWhat would you like to do?n+89:A)Add new accountn+90:R)
26、Remove accountn+91:P)Print statisticsn+92:E)End sessionn);93:94:46函数成函数成员实例方法:实例函数组静态方法:静态方法组类的所有对象共享每个实例方法的一个拷贝:编译器将此方法所调用对象的引用作为一个参数暗中传递给实例方法。47Method:=where:=():=:=:=new :=static :=virtual :=sealed :=override :=abstract :=extern :=public :=private :=protected :=internal :=protected internal :=voi
27、d :=48调用一个方法的方式是:在方法的名字后面加上一对包含参数的圆括号,并与形式参数匹配。49静静态方法方法调用main方法,运行时不会创建任何对象。与其它方法一样,静态方法的定义必须放在类体中。class MyClass().public static void Main().运行时可以直接通过类名调用:Myclass.Main()50调用一个静用一个静态方法的三种途径:方法的三种途径:从方法所属类的内部调用,此时不需要任何类名或对象名作为前缀51从所属类外部调用如果定义方法所在类存在任何一个对象,则可使用此对象名加点操作符来调用:Rocket rocketA=new Rocket();
28、.rocketA.Average(.).不管定义方法所在类是否存在任何对象,都可以通过类名加加点操作符来调用注意:最好使用类名而不是对象名,因为类名调用格式清楚的表示我们正调用一个静态方法。52何何时使用静使用静态方法方法1.不能明确指定属于某一特定对象的方法应该为静态class MyMath .public double Average(params double numbers).如果要调用Average方法:MyMath mathObject=new MyMath();mathObject.Average()将Average声明为staticpublic static double Av
29、erage(params double numbers)调用:MyMath.Average()53技巧:如果程序包含若干不与任何特定对象相关联的方法,提供的功能属于同一个范畴,那么为这些方法创建一个类并声明为static。静态方法遍布.Net框架中。例:System.Math类包含24个静态数学方法。Console类包含Read、ReadLine、Write、WriteLine等542、在某些情况下,使用一个静、在某些情况下,使用一个静态方法来方法来访问静静态成成员变量量55使用使用const关关键字字创建静建静态字段字段const字段是静态字段,但在声明时不适用static关键字const字
30、段一旦声明,其值永远不会改变class Mathcublic const double PI=3.1415926;56所有的静态变量必须声明为Private,当从类的外部访问时,私有静态变量只能通过静态方法进行访问或通过在同一类中作为变量定义的实例方法来访问。不能从同一个类的静态方法内直接访问和调用实例变量及实例方法静态方法与一个类而不是与任何特定对象相关联。实例方法和实例变量属于一个类的特定对象。静态和实例类成员的这一区别导致不能从同一类的静态方法内部直接调用一个实例方法或直接访问一个实例变量。5701:using System;02:03:class Light04:06:public c
31、onst double Speed=299792;07:private double timeTraveled;08:private double distanceTraveled;09:10:public static double CalculateDistance(double seconds)11:12:return seconds*Speed;13:14:15:public static double CalculateTime(double distance)16:17:Light someLight=new Light();18:someLight.SetDistanceTrav
32、eled(distance);19:return someLight.GetTimeTraveled();20:21:22:public void SetTimeTraveled(double newTimeTraveled)23:24:timeTraveled=newTimeTraveled;25:5827:public void SetDistanceTraveled(double newDistanceTraveled)28:distanceTraveled=newDistanceTraveled;32:public double GetDistanceTraveled()33:retu
33、rn CalculateDistance(timeTraveled);37:public double GetTimeTraveled()38:return distanceTraveled/Speed;41:43:class SolarSystem44:45:public static void Main()46:47:Light sunRay=new Light();49:Console.WriteLine(Speed of light:0 kilometers per hour,Light.Speed);50:sunRay.SetTimeTraveled(240);51:Console.
34、WriteLine(The sunray has traveled 0 kilometers after 240 seconds,52:sunRay.GetDistanceTraveled();53:Console.WriteLine(Light travels 0 kilometers after 480 seconds,54:Light.CalculateDistance(480);55:Console.WriteLine(It takes 0:N2 seconds for a ray of sunshine,56:Light.CalculateTime(150000000);57:Con
35、sole.WriteLine(to travel from the sun to the earth);58:59:59用用this关关键字自引用字自引用this是一个特殊的引用(指是一个特殊的引用(指针),它指向的是),它指向的是“自己自己”,也,也就是当前就是当前对象象当需要当需要对当前当前对象的引用象的引用时,this关关键字写在方法体内。字写在方法体内。this的作用:的作用:点取成点取成员区分同名区分同名变量量将当前将当前对象(自己)作象(自己)作为参数,参数,传递给其他其他对象的方象的方法法作作为方法名表示构造方法方法名表示构造方法606101:using System;03:cl
36、ass Book04:05:private string title;06:private uint numberOfPages;07:private double weight;09:public void SetAll(string title,uint numberOfPages,double weight)10:11:this.title=title;12:this.numberOfPages=numberOfPages;13:this.weight=weight;14:16:public double GetWeight()17:18:return weight;19:21:publ
37、ic void PrintShippingCost()22:23:Console.WriteLine(nCost of shipping 0:1:C,title,Dispatcher.ShippingCost(this);25:27:public Book GetHeavierBook(Book aBook)28:29:if(weight aBook.GetWeight()30:return this;31:else32:return aBook;33:34:区区别别形形式式参参数数、本本地地变量与实例变量变量与实例变量this的作用的作用162 36:class Dispatcher37:3
38、8:public static decimal ShippingCost(Book bookToSend)39:40:return 5m+(decimal)(bookToSend.GetWeight()*3);41:42:43:44:class VirtualBookshop45:46:public static void Main()47:48:Book myBook=new Book();49:Book yourBook=new Book();50:Book heavierBook;51:52:myBook.SetAll(“计算机系统结构,400,2.3);53:Console.Write
39、Line(Shipping cost:0:C,Dispatcher.ShippingCost(myBook);54:myBook.PrintShippingCost();56:yourBook.SetAll(“微机原理,610,3.1);57:heavierBook=yourBook.GetHeavierBook(myBook);58:heavierBook.PrintShippingCost();59:60:作作为为一一个个参参数数将将当当前前对对象象的的引用传递给另一个方法引用传递给另一个方法将将当当前前对对象象的的引引用用返返回回给给方方法法的调用者的调用者63只只读成成员(readon
40、ly member)与常量成员(由const关键字声明)一样,只读成员也用于表示一个不变化的值。但是,赋值给常量的值必须在源代码中指定,如:const decimal MassOfElectron=9.0E-28m;只读成员的值直到程序运行时才知道只读成员的值在一个构造函数中初始化,而且此后不能再修改。所以,常量成员在编译后程序的整个生存期内保持不变,而只读成员只在此对象的生存期内保持不变。常量成员的类型限于以下之一:byte、sbyte、short、ushort、int、uint、long、float、double、decimal、char、bool、enum、string只读成员可以为任何
41、类型6401:using System;02:03:class Account04:05:public readonly string AccountNumber;06:07:public Account(string permanentAccountNumber)08:09:AccountNumber=permanentAccountNumber;10:11:12:13:class SimpleBank14:15:public static void Main()16:17:Account yourAccount=new Account(8487-9873-9938);18:Console.
42、WriteLine(Your account number:“19:+yourAccount.AccountNumber);20:21:6513.4 垃圾回收:自垃圾回收:自动动态内存管理内存管理01:using System;02:03:class Account04:05:06:07:08:class Bank09:10:private Account bankAccount;11:12:public void SetAccount(Account newAccount)13:14:bankAccount=newAccount;15:16:17:18:class Tester19:20:p
43、ublic static void Main()21:22:Bank bank1;24:Account account1;25:Account account2;27:account1=new Account();29:account1=null;31:account1=new Account();32:account2=new Account();34:account1=account2;36:bank1=new Bank();37:bank1.SetAccount(new Account();39:bank1=null;41:DoingAccountStuff();42:44:public
44、 static void DoingAccountStuff()45:46:Account localAccount;47:localAccount=new Account();48:49:667.5.3静静态类C#语言允许将一个类声明为静态类静态类只包含静态成员(使用该类创建的所有对象将共享这些成员的同一个副本)静态类纯粹作为工具方法和字段的一个容器使用静态类不能包含任何实例数据或方法使用new操作符来创建静态类的一个对象是没有意义的,编译器会报错如果需要任何初始化,静态类可以包含一个默认构造器,该构造器也必须是静态的7.5.4匿名匿名类匿名类是没有名字的类匿名类的创建方法:new关键字开头,后跟一对,并在花括号内定义想在类中包含的字段和值,例如myAnonymousObject=new Name=John,Age=44;定义一个匿名类时,编译器会为这个类生成一个只有它自己才知道的名称问题:不知道类的名称,如何创建一个恰当类型的对象?答案:不需要知道67然而,在使用了var关键字的前提下,对变量进行初始化的表达式是什么类型,编译器就用这个类型来创建变量var myAnonymousObject=new Name=John,Age=44;68课本本130页练习69