C#中的面向对象ppt课件_第1页
C#中的面向对象ppt课件_第2页
C#中的面向对象ppt课件_第3页
C#中的面向对象ppt课件_第4页
C#中的面向对象ppt课件_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

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

文档简介

1、第第6章面向对象程序设计章面向对象程序设计 6.1 类类6.2 构造函数和析构函数构造函数和析构函数6.3 静态成员静态成员 6.4 属性属性6.5 6.6 委托委托6.7 事件事件6.9 类的转换类的转换 1;.6.1类类6.1.1类的定义类的定义类的修饰符类的修饰符 class 类名类名 :基类名基类名 成员访问修饰符成员访问修饰符 类的成员类的成员;类的修饰符类的修饰符说明说明public公有类。表示不受限制对该类的访问。公有类。表示不受限制对该类的访问。protected保护类。表示只能从所在类和所在类派生的子类进行访问。保护类。表示只能从所在类和所在类派生的子类进行访问。intern

2、al内部类。只有其所在类才能访问。内部类。只有其所在类才能访问。private私有类。只有该类才能访问。私有类。只有该类才能访问。abstract抽象类。表示该类是一个不完整的类,不允许建立类的实例。抽象类。表示该类是一个不完整的类,不允许建立类的实例。sealed密封类。不允许从该类派生新的类。密封类。不允许从该类派生新的类。2;.using system;namespace Test class Student public string name;/姓名姓名 public int age; /年龄年龄 public void dispdata() Console.WriteLine(“0

3、 1”, pno, pname); class Program static void Main(string args) Student stu1=new Student( ); Student stu2=null; =“恭喜恭喜”; stu1.age=20; stu2=null; stu1.dispdata( ); stu2.dispdata( ); 3;.6.1.2类成员的访问类成员的访问成员访问修饰符成员访问修饰符说明说明public公有的。在程序的任何地方(包括本类和本类外的其他类)公有的。在程序的任何地方(包括本类和本类外的其他类)都可以访问。都可以访问。prot

4、ected保护的。表示只能从所在类和所在类派生的子类进行访问。保护的。表示只能从所在类和所在类派生的子类进行访问。internal内部的。本程序集(同一个命名空间)任何地方可以访问。内部的。本程序集(同一个命名空间)任何地方可以访问。private私有的。只有在本类中才能访问。私有的。只有在本类中才能访问。注:注:internal修饰的成员一个项目里相当于修饰的成员一个项目里相当于public关键字,因为一个项目默认关键字,因为一个项目默认就是一个程序集。就是一个程序集。 readonly只读成员。这类成员的值只能读,不能写。也就是说,除只读成员。这类成员的值只能读,不能写。也就是说,除了赋予

5、初始值外,在程序的任何部分将无法更改这个成员了赋予初始值外,在程序的任何部分将无法更改这个成员的值。的值。4;.using system;namespace Test class Access public int a; private int b; protected int c; internal int d; private int GetA( ) return a; public int GetSum( ) int r=a+b+c+d; return r; class Program static void Main(string args) Access ac=new Access(

6、 ); ac.a=4; ac.b=5; ac.c=7; ac.d=8; ac.GetA( ); ac.GetSum( ); 5;.6.2静态成员静态成员 关于类的数据成员的存放问题关于类的数据成员的存放问题.6.2.1 静态字段静态字段 静态字段是类中所有对象共享的成员,而不是某个对象的成员,也就是说静态字段是类中所有对象共享的成员,而不是某个对象的成员,也就是说静态字段的存储空间不是放在每个对象中,而是和方法一样放在类公共区中。静态字段的存储空间不是放在每个对象中,而是和方法一样放在类公共区中。 对静态字段的操作和一般字段一样,定义为私有的静态字段不能被外界访对静态字段的操作和一般字段一样,

7、定义为私有的静态字段不能被外界访问。静态字段的使用方法如下:问。静态字段的使用方法如下: (1)静态字段的定义与一般字段相似,但前面要加上)静态字段的定义与一般字段相似,但前面要加上static关键词。关键词。 (2)在访问静态字段时采用如下格式:)在访问静态字段时采用如下格式: 类名类名.静态字段名静态字段名6;.using system;namespace Test class Student public static int studentCounter; public static int AddStudent( ) return +studentCounter; public vo

8、id AddStudentEx( ) + studentCounter; class Test public static void Main( ) Student.studentCounter+; Student e=new Student( ); Console.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); Student.AddStudent( ); Console.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); e. AddStudentEx( ) ;

9、Console.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); 7;.6.2.2 静态方法静态方法 静态方法与静态字段类似,也是从属于类,都是类的静态成员。只要类存静态方法与静态字段类似,也是从属于类,都是类的静态成员。只要类存在,静态方法就可以使用,静态方法的定义是在一般方法定义前加上在,静态方法就可以使用,静态方法的定义是在一般方法定义前加上static关关键字。调用静态方法的格式如下:键字。调用静态方法的格式如下: 类名类名.静态方法名静态方法名(参数表参数表); 注意:静态方法只能访问静态字段、其他静态方法和类以外的函数

10、及数据,注意:静态方法只能访问静态字段、其他静态方法和类以外的函数及数据,不能访问类中的非静态成员(因为非静态成员只有对象存在时才有意义)。不能访问类中的非静态成员(因为非静态成员只有对象存在时才有意义)。但静态字段和静态方法可由任意访问权限许可的成员访问。但静态字段和静态方法可由任意访问权限许可的成员访问。8;.using system;namespace Test class Student static int studentCounter=0; public static Student GetStudent( ) return new Student( ); public stati

11、c int AddStudent( ) return +studentCounter; public void AddStudentEx( ) AddStudent( ); + studentCounter; class Test public static void Main( ) Student.studentCounter+; Student e=new Student.GetStudent( ); Console.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); Student.AddStudent( ); Console

12、.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); e. AddStudentEx( ) ; Console.WriteLine(“输出现在的学生数输出现在的学生数:0”, Student.studentCounter); 9;.6.2.3 方法的重载方法的重载重载方法的定义规则如下:重载方法的定义规则如下:1.必须是同一个类中的方法。必须是同一个类中的方法。2.满足方法名字相同、参数不同(指参数个数不同或参数个数相同而参数类满足方法名字相同、参数不同(指参数个数不同或参数个数相同而参数类型不同)。型不同)。3.与方法的访问修饰符

13、和返回值无关。与方法的访问修饰符和返回值无关。10;.重载方法的调用:重载方法的调用:using system;namespace TestAdd public class TestAdd public int Add(int a,int b) return a+b; public double Add(double a,double b) return a+b; public int Add(string a,string b) return Convert.ToInt32(a)+ Convert.ToInt32(b); class Test public static void Main(

14、 ) TestAdd t=new TestAdd( ); t.Add(1,2); t.Add(2.0,3.0); t.Add(“3”, “4”); t.Add(2,3.0); t.Add(“2”,3.0); 如果如果#根据调用参数没根据调用参数没有找到对应的方法,那有找到对应的方法,那么么#将调用带有将调用带有“最近最近”类型参数的方法。类型参数的方法。11;.return Convert.ToInt32(a)+ Convert.ToInt32(b)C#支持三种显示转换:支持三种显示转换:parse方法将字符串数据转换成相应的数值类型方法将字符串数据转换成相应的数值类型convert.To.将

15、源类型转换为目标类型将源类型转换为目标类型12;.示例:示例:using System;namespace Test class Program static void Main( ) int a=int.parse(“3”); int b=(int)3.14; int c=Convert.ToInt32(3.14); float d=Convert.ToSingle(“3.14”); string e=3.ToString( ); Console.WriteLine(“a=0,b=1,c=2,d=3,e=4”,a,b,c,d,e); 运行结果:运行结果:a=3,b=3,c=3,d=3.14,

16、e=3.1413;.6.3 构造方法和析构方法构造方法和析构方法6.3.1构造函数构造函数1. 什么是构造函数什么是构造函数 构造函数是在创建给定类型的对象时执行的类方法。构造函数具有如下性质:构造函数是在创建给定类型的对象时执行的类方法。构造函数具有如下性质:l 构造函数的名称与类的名称相同。构造函数的名称与类的名称相同。l 构造函数尽管是一个函数,但没有任何类型,即它既不属于返回值函数也不构造函数尽管是一个函数,但没有任何类型,即它既不属于返回值函数也不属于属于void函数。函数。l 一个类可以有多个构造函数,但所有构造函数的名称都必须相同,它们的参一个类可以有多个构造函数,但所有构造函数

17、的名称都必须相同,它们的参数各不相同,即构造函数可以重载。数各不相同,即构造函数可以重载。l 当类对象创建时,构造函数会自动地执行;由于它们没有返回类型,因此不当类对象创建时,构造函数会自动地执行;由于它们没有返回类型,因此不能像其他函数那样进行调用。能像其他函数那样进行调用。l 当类对象声明时,调用哪一个构造函数取决于传递给它的参数类型。当类对象声明时,调用哪一个构造函数取决于传递给它的参数类型。l 构造函数不能被继承。构造函数不能被继承。14;.2. 调用构造函数调用构造函数当定义类对象时,构造函数会自动执行。当定义类对象时,构造函数会自动执行。1)调用默认构造函数)调用默认构造函数 不带

18、参数的构造函数称为默认构造函数。无论何时,只要使用不带参数的构造函数称为默认构造函数。无论何时,只要使用new运算符实例运算符实例化对象,并且不为化对象,并且不为new提供任何参数,就会调用默认构造函数。假设一个类包含提供任何参数,就会调用默认构造函数。假设一个类包含有默认构造函数,调用默认构造函数的语法如下:有默认构造函数,调用默认构造函数的语法如下: 类名类名 对象名对象名=new 类名类名(); 如果没有为对象提供构造函数,则默认情况下如果没有为对象提供构造函数,则默认情况下 C#将创建一个构造函数,该构将创建一个构造函数,该构造函数实例化对象,并将所有成员变量设置为相应的默认值。造函数

19、实例化对象,并将所有成员变量设置为相应的默认值。2)调用带参数的构造函数)调用带参数的构造函数 假设一个类中包含有带参数的构造函数,调用这种带参数的构造函数的语法如假设一个类中包含有带参数的构造函数,调用这种带参数的构造函数的语法如下:下:类名类名 对象名对象名=new 类名类名(参数表参数表);15;.【例例6.2】 设计一个控制台应用程序,说明调用构造函数的过程。设计一个控制台应用程序,说明调用构造函数的过程。 namespace Proj6_2 class Program public class TPoint1 /声明类声明类TPoint1 int x, y; /类的私有变量类的私有变

20、量 public TPoint1( ) /默认的构造函数默认的构造函数 public TPoint1(int x1, int y1) /带参数的构造函数带参数的构造函数 x = x1; y = y1; public void dispoint() Console.WriteLine(0,1), x, y); static void Main(string args) TPoint1 p1 = new TPoint1(); /调用默认的构造函数调用默认的构造函数 Console.Write(第一个点第一个点=); p1.dispoint( ); TPoint1 p2 = new TPoint1(

21、8, 3);/调用带参数的构造函数调用带参数的构造函数 Console.Write(第二个点第二个点=); p2.dispoint( ); 16;.6.3.2析构函数析构函数 1. 什么是析构函数什么是析构函数 在对象不再需要时,希望确保它所占的存储空间能被收回。在对象不再需要时,希望确保它所占的存储空间能被收回。C#中提供了析中提供了析构函数用于专门释放被占用的系统资源。析构函数具有如下性质:构函数用于专门释放被占用的系统资源。析构函数具有如下性质:l 析构函数在类对象销毁时自动执行。析构函数在类对象销毁时自动执行。l 一个类只能有一个析构函数,而且析构函数没有参数,即析构函数不能重载。一个

22、类只能有一个析构函数,而且析构函数没有参数,即析构函数不能重载。l 析构函数的名称是析构函数的名称是“”加上类的名称(中间没有空格)。加上类的名称(中间没有空格)。l 与构造函数一样,析构函数也没有返回类型。与构造函数一样,析构函数也没有返回类型。l 析构函数不能被继承。析构函数不能被继承。17;.2. 调用析构函数调用析构函数当一个对象被系统销毁时自动调用类的析构函数。当一个对象被系统销毁时自动调用类的析构函数。18;.【例例6.3】 设计一个控制台应用程序,说明调用析构函数的过程。设计一个控制台应用程序,说明调用析构函数的过程。 using System;namespace Proj6_3

23、 class Program public class TPoint2 /声明类声明类TPoint2 int x, y; public TPoint2(int x1, int y1) /带参数的构造函数带参数的构造函数 x = x1; y = y1; TPoint2( ) Console.WriteLine(点点=(0,1), x, y); static void Main(string args) TPoint2 p1 = new TPoint2(2,6); TPoint2 p2 = new TPoint2(8, 3); 19;.6.4 方法的重载方法的重载 方法的重载是指调用同一方法名,但

24、是使用不同的数据类型参数或者次序方法的重载是指调用同一方法名,但是使用不同的数据类型参数或者次序不一致的参数。只要一个类中有两个以上的同名方法,且使用的参数类型或者不一致的参数。只要一个类中有两个以上的同名方法,且使用的参数类型或者个数不同,编译器就可以判断在哪种情况下调用哪种方法了。个数不同,编译器就可以判断在哪种情况下调用哪种方法了。 为此,为此,C#中引入了成员签名的概念。成员签名包含成员的名称和参数列表,中引入了成员签名的概念。成员签名包含成员的名称和参数列表,每个成员签名在类型中必须是唯一的,只要成员的参数列表不同,成员的名称每个成员签名在类型中必须是唯一的,只要成员的参数列表不同,

25、成员的名称可以相同。如果同一个类有两个或多个这样的成员(方法、属性、构造函数可以相同。如果同一个类有两个或多个这样的成员(方法、属性、构造函数等),它们具有相同的名称和不同的参数列表,则称该同类成员进行了重载,等),它们具有相同的名称和不同的参数列表,则称该同类成员进行了重载,但它们的成员签名是不同的。但它们的成员签名是不同的。 例如,下面的代码实现了例如,下面的代码实现了MethodTest方法的重载(假设都是某个类的成方法的重载(假设都是某个类的成员),它们是不同的成员签名:员),它们是不同的成员签名: 20;.public int MethodTest(int i,int j) /重载方

26、法重载方法1/代码代码public int MethodTest(int i) /重载方法重载方法2/代码代码public string MethodTest(string sr)/重载方法重载方法3/代码代码21;.6.5属性属性6.5.1什么是属性什么是属性 属性描述了对象的具体特性,它提供了对类或对象成员的访问。属性描述了对象的具体特性,它提供了对类或对象成员的访问。 C#中的属性更充分地体现了对象的封装性,属性不直接操作类的字段,而是中的属性更充分地体现了对象的封装性,属性不直接操作类的字段,而是通过访问器进行访问。通过访问器进行访问。22;.一个关于银行自动取款机的一个关于银行自动取

27、款机的ATM系统系统class ATMAccount public int type; /账户类型账户类型 public double balance; /账户余额账户余额 public int accountNumber; /账户号码账户号码如果我们这样使用会有什么后果如果我们这样使用会有什么后果?ATMAccount ac=new ATMAccount( );ac.accountNumber=1001;ac.balance=1000;23;.改进的银行自动取款机的改进的银行自动取款机的ATM系统系统class ATMAccount private int type; /账户类型账户类型 p

28、rivate double balance; /账户余额账户余额 private int accountNumber; /账户号码账户号码 public int Type get return type; settype=value; public double Balance get return balance; setbalance=value; public int GetAccountNumber get return accountNumber; 24;.6.5.2属性声明属性声明 属性在类模块里是采用下面的方式进行声明的,即指定变量的访问级别、属属性在类模块里是采用下面的方式进行

29、声明的,即指定变量的访问级别、属性的类型、属性的名称,然后是性的类型、属性的名称,然后是get访问器或者访问器或者set访问器代码块。其语法格式访问器代码块。其语法格式如下:如下: 修饰符修饰符 数据类型数据类型 属性名称属性名称 get访问器访问器 set访问器访问器 其中,修饰符有其中,修饰符有new、public、protected、internal、private、static、virtual、override和和abstract。25;.set和和get访问器的三种访问权限访问器的三种访问权限:1.可读可写可读可写 public string Name getreturn name;

30、 setname=value; 2.只读只读 public string Name getreturn name; 3.只写只写 public string Name setname=value; 26;.【例例6.7】 设计一个控制台应用程序,说明属性的使用。设计一个控制台应用程序,说明属性的使用。using System;namespace Proj6_7 public class TPoint3 /声明类声明类TPoint3 int x,y; public int px get return x; /get访问器访问器 set x = value; /set访问器访问器 public i

31、nt py get return y; /get访问器访问器set y = value; /set访问器访问器 ; class Program static void Main(string args) TPoint3 p = new TPoint3( ); p.px = 3; p.py = 8; /调用调用set访问器访问器 Console.WriteLine(点点=(0,1), p.px, p.py); /调用调用get访问器访问器 点点=(3,8)27;.属性的本质就是方法属性的本质就是方法,几种合法属性的定义方式几种合法属性的定义方式:(一一) public string Name g

32、etreturn “wang li”; setname= “wang li”; (二二) class Girl private string id; public string Name getreturn id; setid= value; 属性不一定要和属性不一定要和数据成员绑定。数据成员绑定。属性绑定的数据成员是不属性绑定的数据成员是不受限制的,但最好从属性受限制的,但最好从属性名能直接看出它和哪个数名能直接看出它和哪个数据成员关联。据成员关联。28;.属性的本质就是方法属性的本质就是方法,几种合法属性的定义方式几种合法属性的定义方式:(三三) public static string

33、Name getreturn name; setname= value; (四四) public static string Name private getreturn name; protected setname= value; 属性可以是静态属性可以是静态的。的。get和和set访问器可以有各访问器可以有各自的访问修饰符,但一般自的访问修饰符,但一般情况下都不用,不写的话情况下都不用,不写的话表示表示public类型。类型。29;.思考思考:使用同时包含使用同时包含get和和set访问器的属性与使用公有字访问器的属性与使用公有字段有何区别段有何区别?区别:属性是特殊的方法,使用灵活,在

34、其访问函数区别:属性是特殊的方法,使用灵活,在其访问函数中还可以进行各种控制和计算。例如:中还可以进行各种控制和计算。例如:30;.using System;namespace Bankpublic class BankCard private string id; /私有字段私有字段 private string password;/字段字段 private decimal money;/字段字段 public string Id /属性属性 getreturn id; public decimal Money /属性属性 getConsole.Write(“请输入密码:请输入密码:”);

35、if(Console.ReadLine()!=password) Console.WriteLine(“密码错误密码错误”);return 0; else return money; public BankCard(string s,string p) /构造函数构造函数 id=s; password=p; public void Deposit(decimal x) /方法方法 money+=x; class Program static void Main( ) /主方法主方法 BankCard card1=new BankCard(“001”, (“8888”); card1.Depos

36、it(800); Console.WriteLine(“余额余额0”,card1.Money);/调用调用get访问函数访问函数31;.注意:注意:1、属性和字段最大的区别在于它并不实际存储变量的值。、属性和字段最大的区别在于它并不实际存储变量的值。2、C#3.0版本开始支持版本开始支持“自动属性自动属性”技术,仅限于读写操作的属性,即技术,仅限于读写操作的属性,即 public string Name get; set; 32;.6.6 索引器索引器6.6.1 什么是索引器什么是索引器 索引器是属性的一种,用索引器完成对数组或集合数据访问权限的控制。索引器是属性的一种,用索引器完成对数组或集

37、合数据访问权限的控制。 索引器与属性的不同之处:索引器与属性的不同之处: 索引函数以索引函数以this关键字加数组下标关键字加数组下标 进行定义进行定义 索引函数的索引函数的get和和set访问函数有一个专门的参数来表示数组下标访问函数有一个专门的参数来表示数组下标 索引函数不能是静态的索引函数不能是静态的33;.6.9.2 定义索引器定义索引器索引器语法格式如下:索引器语法格式如下:访问修饰访问修饰 返回类型返回类型 thisint index / get和和set访问器访问器 示例:示例: public string thisint n getreturn namen; setnamen=

38、value;34;. public class University const int MAX = 5; private string name = new stringMAX; public string thisint index /索引器索引器 get if (index = 0 & index = 0 & index MAX) nameindex = value; 例如,带有索引器的例如,带有索引器的University类设计如下:类设计如下:35;.6.7委托委托6.7.1 什么是委托什么是委托 C+、Pascal和其他语言支持函数指针的概念,允许在运行时选择要调用

39、和其他语言支持函数指针的概念,允许在运行时选择要调用的函数。的函数。Java不提供任何具有函数指针功能的结构,但不提供任何具有函数指针功能的结构,但C#提供这种结构。通提供这种结构。通过使用过使用Delegate类,委托实例可以封装属于可调用实体的方法。类,委托实例可以封装属于可调用实体的方法。36;.6.7.2 定义和使用委托定义和使用委托定义和使用委托有定义和使用委托有3个步骤,即声明、实例化和调用。个步骤,即声明、实例化和调用。1. 声明委托类型声明委托类型 声明委托类型就是告诉编译器这种委托类型代表了哪种类型的方法。使用声明委托类型就是告诉编译器这种委托类型代表了哪种类型的方法。使用以

40、下语法声明委托类型:以下语法声明委托类型: 修饰符修饰符 delegate 返回类型返回类型 委托类型名委托类型名(参数列表参数列表); 例如例如: private delegate void mydelegate(int n); 上述代码声明了一个委托上述代码声明了一个委托mydelegate,该委托类型可以引用一个采用,该委托类型可以引用一个采用int作作为参数并返回为参数并返回void的方法。的方法。37;.2. 创建委托对象创建委托对象 声明了委托类型后,必须创建一个它的实例,即创建委托对象并使之与声明了委托类型后,必须创建一个它的实例,即创建委托对象并使之与特定方法关联。定义委托对象

41、的语法格式如下:特定方法关联。定义委托对象的语法格式如下: 委托类型名委托类型名 委托对象名委托对象名; 例如,以下语句创建了例如,以下语句创建了mydelegate委托的一个委托对象委托的一个委托对象p: mydelegate p;38;. 另外,委托对象还需实例化为调用的方法,通常将这些方法放在一个类中(也另外,委托对象还需实例化为调用的方法,通常将这些方法放在一个类中(也可以将这些方法放在程序的可以将这些方法放在程序的Program类中),假设一个类中),假设一个MyDeClass类如下:类如下: class MyDeClass public void fun1(int n) Conso

42、le.WriteLine(0的的2倍倍=1,n,2*n); public void fun2(int n) Console.WriteLine(0的的3倍倍=1, n, 3 * n); 可以通过以下语句实例化委托对象可以通过以下语句实例化委托对象p: MyDeClass obj = new MyDeClass(); mydelegate p = new mydelegate(obj.fun1); 其中,其中,MyDeClass类中的类中的fun1方法有一个方法有一个int形参,其返回类型为形参,其返回类型为void,它必须,它必须与与mydelegate类型的声明相一致。类型的声明相一致。39

43、;.3. 调用委托调用委托其使用语法格式如下:其使用语法格式如下: 委托对象名委托对象名(实参列表实参列表); 例如,以下语句调用委托例如,以下语句调用委托p: p(100); 委托对象是不可变的,即设置与它们匹配的签名后就不能再更改签名了。委托对象是不可变的,即设置与它们匹配的签名后就不能再更改签名了。但是,如果其他方法具有同一签名,也可以指向该方法。例如:但是,如果其他方法具有同一签名,也可以指向该方法。例如: MyDeClass obj = new MyDeClass(); mydelegate p = new mydelegate(obj.fun1); p(5); p = new my

44、delegate(obj.fun2); p(3);40;.【例例6.9】 设计一个控制台应用程序,说明委托的使用。设计一个控制台应用程序,说明委托的使用。 using System;namespace Proj6_9 delegate double mydelegate(double x,double y);/声明委托类型声明委托类型 class MyDeClass public double add(double x, double y) return x+y; public double sub(double x,double y) return x-y; public double mu

45、l(double x,double y) return x*y; public double div(double x,double y) return x/y; 41;. class Program static void Main(string args) MyDeClass obj = new MyDeClass(); mydelegate p = new mydelegate(obj.add); Console.WriteLine(5+8=0,p(5,8); p = new mydelegate(obj.sub); Console.WriteLine(5-8=0,p(5,8); p =

46、 new mydelegate(obj.mul); Console.WriteLine(5*8=0,p(5,8); p = new mydelegate(obj.div); Console.WriteLine(5/8=0,p(5,8); 42;. 还可以直接写成如下代码还可以直接写成如下代码:static void Main(string args) MyDeClass obj = new MyDeClass(); mydelegate p = obj.add; Console.WriteLine(5+8=0, p(5, 8); p = obj.sub; Console.WriteLine(5

47、-8=0, p(5, 8); p = obj.mul; Console.WriteLine(5*8=0, p(5, 8); p = obj.div; Console.WriteLine(5/8=0, p(5, 8); 43;.6.7.3 委托对象封装多个方法委托对象封装多个方法(多播委托多播委托) 委托对象可以封装多个方法,这些方法的集合称为委托链。委托使用委托对象可以封装多个方法,这些方法的集合称为委托链。委托使用“+”、“-”、“+=”和和“-=”运算符向调用列表中增加或移除处理方法。运算符向调用列表中增加或移除处理方法。 44;.【例例6.10】 设计一个控制台应用程序,多播委托的使用。

48、设计一个控制台应用程序,多播委托的使用。 using System;namespace Proj6_10 delegate void mydelegate(double x, double y);/声明委托类型声明委托类型 class MyDeClass public void add(double x, double y) Console.WriteLine(0+1=2,x,y,x + y); public void sub(double x, double y) Console.WriteLine(0-1=2, x, y, x - y); public void mul(double x,

49、 double y) Console.WriteLine(0*1=2, x, y, x * y); public void div(double x, double y) Console.WriteLine(0/1=2, x, y, x/y); 45;. class Program static void Main(string args) MyDeClass obj = new MyDeClass(); mydelegate p, a; a = obj.add; p = a; /将将add方法添加到委托链中方法添加到委托链中 a = obj.sub; p += a; /将将sub方法添加到委

50、托链中方法添加到委托链中 a = obj.mul; p += a; /将将mul方法添加到委托链中方法添加到委托链中 a = obj.div; p += a; /将将div方法添加到委托链中方法添加到委托链中 p(5, 8); /调用委托调用委托 46;.使用多播委托应该注意的问题:使用多播委托应该注意的问题:(1)多播委托的委托方法最好是没有返回值的方法,也就是)多播委托的委托方法最好是没有返回值的方法,也就是void方法方法,如果委托了如果委托了带有返回值的方法也无法获得级联的结果。带有返回值的方法也无法获得级联的结果。using System;namespace Proj6_10 del

51、egate int mydelegate(int x, int y);/声明委托类型声明委托类型,可直接在命名空间下可直接在命名空间下 class MyDeClass public static int add(int x, int y) return x + y; public static int sub(int x, int y) return x - y; static void Main( ) mydelegate p= MyDeClass.add; /委托静态方法,不需要类的实例委托静态方法,不需要类的实例 p+= MyDeClass.sub; int result=p(4,6);

52、 Console.WriteLine(“结果是结果是0”,result) ; 结果是结果是-2。47;.(2)多播委托只支持)多播委托只支持“+”、“-”、“+=”和和“-=”四种运算。例子:四种运算。例子:using System;namespace Proj6_10 delegate void Del(string s);/声明委托类型声明委托类型,可直接在命名空间下可直接在命名空间下 class TestClass static void Hello(string s)Console.WriteLine(“Hello,0!”,s); static void Goodbye(string

53、s)Console.WriteLine(“Goodbye,0!”,s); static void Main( ) Del a,b,c,d; a=TestClass. Hello; b=TestClass. Goodbye; c=a+b; /建立组合委托建立组合委托c,是是a、b两个委托组成的委托链两个委托组成的委托链 d=c-a; /从委托链中去除从委托链中去除a委托委托 Console.WriteLine(“调用委托调用委托a:”); a(“A”); Console.WriteLine(“调用委托调用委托b:”); b(“B”); Console.WriteLine(“调用委托调用委托c:”

54、); c(“C”); Console.WriteLine(“调用委托调用委托d:”); d(“D”); 结果是:结果是:调用委托调用委托a:Hello,A!调用委托调用委托b:Goodbye,B!调用委托调用委托c:Hello,C!Goodbye,C!调用委托调用委托d:Goodbye,D!48;.6.7.4 使委托与匿名方法关联使委托与匿名方法关联 所谓匿名方法就是没有方法名称的方法。当将委托与匿名方法关联时,直接给所谓匿名方法就是没有方法名称的方法。当将委托与匿名方法关联时,直接给出方法的函数体,其一般语法格式如下:出方法的函数体,其一般语法格式如下: delegate 返回类型返回类型

55、委托类型名委托类型名(参数列表参数列表); 委托类型名委托类型名 委托对象名委托对象名=返回类型返回类型(参数列表参数列表) /*匿名方法代码匿名方法代码*/ ; 托对象名托对象名(实参列表实参列表) 第第1个语句声明委托类型;第个语句声明委托类型;第2个语句定义匿名方法并将其与委托对象关联;第个语句定义匿名方法并将其与委托对象关联;第3个语句调用委托。个语句调用委托。49;. 例如,以下程序段就是使委托与匿名方法关联,并调用该委托:例如,以下程序段就是使委托与匿名方法关联,并调用该委托: delegate void mydelegate(string mystr); /声明委托类型声明委托类

56、型 class Program static void Main(string args) mydelegate p = delegate(string mystr) Console.WriteLine(mystr); ; p(String);/输出:输出:String 50;.6.8事件事件 6.8.1 什么是事件什么是事件 事件是类在发生其关注的事情时用来提供通知的一种方式。例如,封装用户界事件是类在发生其关注的事情时用来提供通知的一种方式。例如,封装用户界面控件的类可以定义一个在用户单击时候发生的一个事件。控件类不关心单击按面控件的类可以定义一个在用户单击时候发生的一个事件。控件类不关心

57、单击按钮时候发生了什么,但是它需要告知派生类单击事件已经发生,然后,派生类可钮时候发生了什么,但是它需要告知派生类单击事件已经发生,然后,派生类可以选择如何响应。以选择如何响应。 当发生与某个对象相关的事件时,类和结构会使用事件将这一个对象通知给用当发生与某个对象相关的事件时,类和结构会使用事件将这一个对象通知给用户。这种通知即为引发事件。引发事件的对象称为事件的源或者发送者。对象引户。这种通知即为引发事件。引发事件的对象称为事件的源或者发送者。对象引发事件的原因很多,如响应时丢失网络连接就会引发一个事件。表示用户界面元发事件的原因很多,如响应时丢失网络连接就会引发一个事件。表示用户界面元素的

58、对象通常会引发事件来响应用户的操作,如按钮单击或者菜单选择。素的对象通常会引发事件来响应用户的操作,如按钮单击或者菜单选择。51;.6.8.2 事件的创建和使用事件的创建和使用 下面介绍在下面介绍在C#中创建和使用事件的步骤。中创建和使用事件的步骤。1. 为事件创建一个委托类型为事件创建一个委托类型 所有事件是通过委托来激活的,其返回值类型一般为所有事件是通过委托来激活的,其返回值类型一般为void型。为事件创建型。为事件创建一个委托类型的语法格式如下:一个委托类型的语法格式如下:delegate void 委托类型名委托类型名(触发事件的对象名,事件参数触发事件的对象名,事件参数); 例如,

59、以下语句创建一个委托类型例如,以下语句创建一个委托类型mydelegate,其委托的事件处理方法返,其委托的事件处理方法返回类型为回类型为void,不带任何参数:,不带任何参数: public delegate void mydelegate();52;.2. 创建事件处理的方法创建事件处理的方法 当事件触发时要调用事件处理方法,需设计相应的事件处理方法,可以将当事件触发时要调用事件处理方法,需设计相应的事件处理方法,可以将它放在单独的类中,也可以放在触发事件的类中。它放在单独的类中,也可以放在触发事件的类中。 例如,以下设计一个包含事件处理方法的单独类例如,以下设计一个包含事件处理方法的单独

60、类 class MyEventHander public void OnHandler1() Console.WriteLine(调用调用OnHandler1方法方法); 53;.3. 声明事件声明事件 事件是类成员,以关键字事件是类成员,以关键字event声明,其一般语法格式如下:声明,其一般语法格式如下: 修饰符修饰符 event 委托类型名委托类型名 事件名事件名; 其中,其中,“修饰符修饰符”指出类的用户访问事件的方式,可以为指出类的用户访问事件的方式,可以为public 、private、protected、internal、protectedinternal、static或或virtual等。等

温馨提示

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

评论

0/150

提交评论