收藏 分享(赏)

c#第3讲 c#面向对象的编程.ppt

上传人:hwpkd79526 文档编号:10023638 上传时间:2019-09-29 格式:PPT 页数:75 大小:572KB
下载 相关 举报
c#第3讲 c#面向对象的编程.ppt_第1页
第1页 / 共75页
c#第3讲 c#面向对象的编程.ppt_第2页
第2页 / 共75页
c#第3讲 c#面向对象的编程.ppt_第3页
第3页 / 共75页
c#第3讲 c#面向对象的编程.ppt_第4页
第4页 / 共75页
c#第3讲 c#面向对象的编程.ppt_第5页
第5页 / 共75页
点击查看更多>>
资源描述

1、第三章,c#面向对象的编程,2,本章目标,类的定义,3,类的定义,类的定义使用class关键字,其基本结构如下:访问修饰符 class 类名/类的主体 访问修饰符可以是public,protected,internal,private和protected internal。具体功能见下表。 访问修饰符可以省略,省略访问修饰符则默认为:private。,4,类的访问修饰符,5,类的成员,组成类的元素称为类的成员,类的成员主要包括描述状态的数据成员和描述操作的方法成员。 数据成员包括字段和属性,6,数据成员5-1,1、字段字段用于存储类要满足其设计所需要的数据。 字段的声明格式如下:访问修饰符 数

2、据类型 字段名称 访问修饰符可以是:public,protected,internal,private和protected internal。 可以选择将字段声明为static,即静态类型。这使得调用者在任何时候都可以使用该字段,即使没有创建该类的任何实例。,7,数据成员5-2,字段可以使用readonly标记声明为只读字段。只读字段只能在初始化期间或在构造函数中赋值,以后将不能对其字段值进行修改。,8,数据成员5-3,class student public string name;public string xh;public static string strAdd;public rea

3、donly string ID; ,9,数据成员5-4,2、属性 属性主要是用来读取、设置或计算类的私有字段的值。 属性充分体现了对象的封装性。 属性拥有访问器,通过属性的get 和set 访问器来实现对私有字段的读写操作。,10,数据成员5-5,class student public string name;public string xh;public static string strAdd;public readonly string ID;private string phoneNumber;public string phoneNumber get return phoneNum

4、ber;set phoneNumber=value; ,11,方法成员,方法是用来描述对象的行为的,对类的数据成员的操作都封装在类的方法中。 方法的声明格式如下:,访问修饰符 方法返回值类型 方法名(参数列表) /方法体,访问修饰符(可选),默认情况下为 private,如果不需要返回任何值,方法可能返回 void 数据类型,方法可以有参数,也可以没有参数,多个参数之间用“,”分隔,没有参数也不能省略( )。,12,声明方法 举例, class Point int x;int y;void Assign()System.Console.WriteLine(“输入点的值“);x = int.Pa

5、rse(System.Console.ReadLine();y = int.Parse(System.Console.ReadLine(); ,方法 Assign() 的定义,不返回任何值 (void)不接收任何值 (Assign(),Assign( ) 方法,13,调用方法 3-1,语法,对象名.方法名(参数列表);,实例,类中的方法,点号,14,演示:示例 3,调用方法 3-2,private void Accept()Console.WriteLine(“请输入实数部分“);_real = int.Parse(Console.ReadLine();Console.WriteLine(“请

6、输入虚数部分“);_imaginary = int.Parse(Console.ReadLine();void ShowResult()Console.WriteLine(“相加之和为:“);Console.WriteLine(_real + “+“ + _imaginary + “i“);/ 此方法用于将两个复数相加ComplexNumber Add(ComplexNumber objParam1)objParam1._real += _real ;objParam1._imaginary += _imaginary;return objParam1;,接收实部和虚部的值,显示实部和虚部的值

7、,请参阅对象的实例变量,objParam1 与 objNumber2 相关联,STAThread public static void Main(string args) ComplexNumber objNumber1 = new ComplexNumber();ComplexNumber objNumber2 = new ComplexNumber();objNumber1.Accept();objNumber2.Accept();ComplexNumber objTemp = objNumber1.Add(objNumber2);objTemp.ShowResult(); ,15,调用方

8、法 3-3,语法,return 表达式;,return 语句,16,方法的参数传递- ref关键字,一般来说,在定义函数时函数名后面括号中的变量称为“形式参数”(简称“形参”),在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”(简称“实参”)。 在C# 中,实参向形参的数据传递都是“值传递”。 其含义是,单向传递,只能由实参传递给形参,而不能由形参传回来给实参,即对形参的任何修改都不影响实参。 可以通过引用传递参数,即函数形参与函数调用中实参相同,函数引用的形参是实参的一个副本,对这个形参进行的任何改变都会影响实参。 还可以使用ref关键字指定参数为引用参数。即如果把一个实参

9、传递给函数,且这个函数的参数前带有ref关键字,则该函数对形参所作的任何改变都会影响实参的值。,17,class Programprivate void swap(ref int num1, ref int num2)int temp;temp = num1;num1 = num2;num2 = temp;static void Main(string args)int num1 = 7;int num2 = 9;Console.WriteLine(“交换前的顺序0,1“, num1, num2);Program pr = new Program();pr.swap(num1, num2);C

10、onsole.WriteLine(“交换后的顺序0,1“, num1, num2);,18,class Programprivate void swap(int num1, int num2)int temp;temp = num1;num1 = num2;num2 = temp;static void Main(string args)int num1 = 7;int num2 = 9;Console.WriteLine(“交换前的顺序0,1“, num1, num2);Program pr = new Program();pr.swap(ref num1, ref num2);Consol

11、e.WriteLine(“交换后的顺序0,1“, num1, num2);,19,方法的参数传递- out关键字,当希望方法返回多个值时,可以使用out参数。,class Programprivate void methodout(out int a, out int b,out string s1)a=27;b=54;s1=“out参数传递“;static void Main(string args)int k, l;string str;Program pr = new Program();pr.methodout(out k, out l, out str);Console.WriteL

12、ine(“k的值:0“, k);Console.WriteLine(“l的值:0“, l);Console.WriteLine(“str的值:0“,str); ,20,构造函数,构造函数是类的一种特殊方法,构造函数的名称和类名相同。每个类都有构造函数(除类是static的),若定义类时,没有定义构造函数,系统会自动提供一个默认的构造函数。默认的构造函数什么都不做。,访问修饰符,(),/ 构造函数的主体 ,语法:,构造函数主要功能是对的实例化对象设置默认值,因此在构造函数中尽量不要做对类的实例进行初始化以外的事情。构造函数分为有参构造函数和无参构造函数。构造函数没有返回值,不能被显示地调用。,2

13、1,析构函数,析构函数用于销毁类的实例 。 类的析构函数是用类名和前缀来声明的。当进行无用存储单元收集时,就执行析构函数中的代码,释放资源。,class MyClassMyClass()/destructor code ,通常析构函数的编写是不必要的,因为.NET Framework会代替开发人员做绝大部分的工作。当某个类的实例被认为不再有效符合析构的条件时,析构函数可能在某个时刻被自动执行。,22,分部类,一般说来,一个类、结构或接口位于一个源文件中,但某些情况,比如大型项目、特殊部署时,可能需要把一个类、结构或接口放在几个文件中来处理。等到编译时,自动地把他们组合起来成为一个完整的类,这就

14、得使用分部类。 C#分部类是在class前面添加关键字partial来定义。,文件ab1.cs public partial class Person public void DoWork() ,文件ab2.cs public partial class Person public void GoToLunch() ,Person类编译后拥有DoWork()和 GoToLunch()两个方法,23,使用静态类2-1,静态类和类成员用于创建无需创建类的实例就能够访问的数据和函数。 可以使用static关键字将类声明为静态类。 静态类仅包含静态成员;不能被实例化;不能包含构造函数,但仍可声明静态构

15、造函数以分配初始值或设置某个静态状态。 静态类是密封的,不能被继承。,24,使用静态类2-2,public static class info private static string user_name = “sa“; private static int exam_id = 1; public static string Name get return user_name; public static int ID get return exam_id; ,面向对象的重要特征,26,基本内容,继承 多态 接口 抽象类和密封类 委托 索引器 事件,27,继承概念2-1,继承是软件复用的一种

16、形式。 类可以从其他类中继承方法和属性。被继承的类成为基类,继承了基类的新类称为派生类。 继承是可传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。Object 类作为所有类的基类。 派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。 构造函数和析构函数不能被继承 。,28,继承概念2-2,派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不因为这派生类删除了这些成员,只是不能再访问这些成员。 类可以定义虚方法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性

17、。 派生类只能从一个类中继承,但可以通过接口实现多重继承 。,29,继承的实现2-1,派生类继承基类的语法是:,访问修饰符 class 派生类名:基类名/类代码,30,继承的实现2-2,public class BaseClass public double a;public double b;public void showAB()Console.WriteLine(“a=0,b=1”,a,b ,public class ChildClass : BaseClass public double Add()return a+b; ,实例化 ChildClass类 ChildClass cc=n

18、ew ChildClass (); cc.a=5; cc.b=4; cc. showAB(); cc. Add();,31,base和this关键字,base关键字用于从派生类中访问基类的成员 。 访问构造函数的语法格式:访问基类上已被其他方法重写的方法 。其语法格式:,派生类构造函数:base(参数列表),Base:基类方法,32,class personpublic string id;public int age;public string gender;public string gender;public person() public person(string id,string

19、 name, int age, string gender)this. id = id;this. name = name;this. age = age;this. gender = gender;public void displayInf()Console.WriteLine(“0是1性,年龄 2;身份证:3“, name, gender, age,id);,33,class student:personpublic string no;public string class_idpublic student() public student(string id,string name,

20、 int age, string gender):base(id, name,age,gender) public void study() ,34,base和this关键字,this指代类对象本身,用于访问本类的所有常量、字段、属性和方法成员,而且不管访问元素是任何访问级别。因为,this仅仅局限于对象内部,对象外部是无法看到的,这就是this的基本思想。,class Team private string name; public Team(string name) /构造函数 this.name = name; ,35,base和this关键字,this也可以用于引用自身的构造函数。,3

21、6,class bookpublic string isbn;public string title;public string auther;public double pice;public book() public book(string isbn,string title,string auther,double pice)this.isbn = isbn;this.title = title;this.auther = auther;this.pice = pice;public book(string isbn): this(isbn, “未知“, “未知“,0.0) publi

22、c void displayinf()Console.WriteLine(“书号:0“, isbn);Console.WriteLine(“书名:0“, title);Console.WriteLine(“作者:0“, auther);Console.WriteLine(“价格:0“, pice);,37,多态2-1,在c#中,多态的含义是:同一操作作用于不同的类的对象,不同的类的对象进行不同的执行,最后产生不同的执行结果。 C#中支持基于接口的多态和基于继承的多态。基于继承的多态设计在基类中定义方法,并在派生类中重写方法。在基类中用关键字virtual声明的方法叫虚方法。虚方法可以在派生类中

23、被重写。 声明虚方法的语法格式:,访问修饰符 virtual 返回类型 方法名(参数) /方法体 ,38,多态的实现2-2,在派生类中使用override关键字来声明重写,以实现对基类中的需方法修改或重写。从而实现多态。,基类person中的方法 public virtual void display() Console.Write(“person”); ,派生类student中的方法 public override void display() Console.Write(“student”); ,派生类teacher中的方法 public override void display() C

24、onsole.Write(“teacher”); ,!注意:重写时,子类重写方法的访问级别和父类需方法的访问级别相同,39,方法重载、重写和隐藏,重载重载是在同一个作用域内(比如一个类中),定义多个同名的方法,但方法的参数列表不同。 重写基类方法中使用virtual关键字声明的方法和派生类中用override关键字声明的方法名称相同,参数列表也相同。 隐藏基类中的方法不声明为virtual,在派生类中声明与基类方法同名时,需要使用new关键字,以隐藏基类的同名方法。,40,基类person中的方法 public void display() Console.Write(“person”); ,

25、派生类student中的方法 public new void display() Console.Write(“student”); ,41,接口,接口用来描述一种程序的规定,可以定义属于任何类或结构的一组相关行为。接口可由方法、属性、事件、索引器或这4种成员类型的任何组合构成。 接口不能包含常数、字段、运算符、实例构造函数、析构函数。接口成员一定是公共的。接口不能被实例化。 接口的定义:接口名称建议以“I”开头。,访问修饰符 interface 接口名 /接口体 ,!注意:接口不能包含其所定义的成员的任何实现语句,42,接口的实现,定义了接口后,就要在类或结构中实现。实现接口的语法和类的继承

26、一样,都用“:”。,interface Ipoint int x get;set;int y get;set; ,class point:Ipoint private int px;private int py;public point(int x,int y) px=x,py=y;public int x/接口属性实现getreturn px;setpx=value;public int ygetreturn py;setpy=value; ,43,public interface IPict int DeleteImage();void DisplayImage(); ,44,public

27、 class MyImages : IPict /第一个方法的实现 public int DeleteImage()Console.WriteLine(“DeleteImage 实现!“);return(5);/第二个方法的实现 public void DisplayImage()Console.WriteLine(“DisplayImage 实现!“); ,static void Main(string args) MyImages objM = new MyImages();objM.DisplayImage();int t = objM.DeleteImage();Console.Wri

28、teLine(t); ,派生自 IPict 接口,45,public interface IPict int DeleteImage();void DisplayImage(); public class MyImages : BaseIO, IPict public int DeleteImage()Console.WriteLine(“DeleteImage 实现!“);return(5);public void DisplayImage()Console.WriteLine(“DisplayImage 实现!“); ,public class BaseIO public void Ope

29、n()Console.WriteLine(“BaseIO 的 Open 方法“); ,static void Main(string args) MyImages objM = new MyImages();objM.DisplayImage();int val = objM.DeleteImage();Console.WriteLine(val);objM.Open(); ,46,多重接口实现,C# 不允许多重类继承 但 C# 允许多重接口实现 这意味着一个类可以实现多个接口,47,interface Ipeoplevoid print();interface Istudentvoid pr

30、int();class myclass : Ipeople, Istudentvoid Ipeople.print() Console.WriteLine(“people“); void Istudent.print() Console.WriteLine(“student“); ,class Programstatic void Main(string args)myclass my = new myclass();Ipeople ip = (Ipeople)my;Istudent ist=(Istudent)my;ip.print();ist.print();,48,抽象类和抽象方法,用来

31、描述共性的类就是抽象类,抽象类中不考虑具体的实现,只确定必须具有的行为,即抽象方法。抽象类和抽象方法的声明都使用关键字abstract。定义语法:当一个派生类继承一个抽象类时,派生类必须重写实现抽象类的所有抽象方法。, abstract class 抽象类名 abstract 返回类型 抽象方法名(); ,!警告:尽管c#抽象类也可以包含非抽象方法,也就是说为其方法提供了实现,但抽象类不能实例化,不能是静态的或密封的。,49,public abstract class person public abstract void display(); ,public class student: p

32、erson private string name;public student(string name) this.name=name; public override void display()Console.WriteLine(“name:”+name) ,50,密封类,密封类是类的一种,用sealed修饰,不能用作基类。密封类主要用于防止派生。 密封类的定义是通过sealed关键字实现的,如下的代码定义了一个密封类。,sealed class MySealedClass ,51,委托,委托又叫代理,就是把事情交给其他人去做。它实际上相当于C语言的函数指针。与指针不同的是C#中的代表是

33、类型安全的 。 最通俗易懂的话来讲,委托就是用来执行方法(函数)的一个东西 。委托的声明格式:, delegate 返回类型 委托名称(形参列表);,52,委托的使用,声明委托:说明:任何一个返回值为double,且只有一个形参为double的函数,都可以用这个委托来调用。,delegate double MathsOp( double x );,53,委托的使用,实例化: 委托实例化前,首先我们要先有一个满足委托声明的方法,假设一个返回一个数的2倍的方法:,class testpublic static double MultiplyBy2( double value ) return va

34、lue * 2; ,有了方法就可以实例化委托了,实例化如下:,MathsOp operation = new MathsOp( test.MultiplyBy2 );,在实例化完一个委托之后,就可以用这个委托来调用方法了:,double result = operation( 1.23 );,54,namespace ConsoleApplication7 public delegate double MathsOp(double x);class testpublic static double MultiplyBy2( double value )return value * 2;clas

35、s Programstatic void Main(string args)MathsOp operation = new MathsOp(test.MultiplyBy2);double x = 56;double result = operation(x);Console.WriteLine(“0 multiply by 2 is 1“, x, result); ,55,delegate int MyDelegate();class Programpublic int InstanceMethod()Console.WriteLine(“调用了非静态的方法。“);return 0;stat

36、ic public int StaticMethod()Console.WriteLine(“调用了静态的方法。“);return 0;static void Main(string args)Program p = new Program();MyDelegate d = new MyDelegate(p.InstanceMethod);d();/调用非静态方法d = new MyDelegate(Program.StaticMethod);d();/调用静态方法,56,delegate int MyDelegate(string str);class Programpublic int I

37、nstanceMethod(string str)Console.WriteLine(“调用了非静态的方法。“+str);return 0;static public int StaticMethod(string str)Console.WriteLine(“调用了静态的方法。“+str);return 0;static void Main(string args)Program p = new Program();MyDelegate d = new MyDelegate(p.InstanceMethod);d(“hello“);/调用非静态方法d = new MyDelegate(Pro

38、gram.StaticMethod);/参数是被代表的方法d(“good“);/调用静态方法,57,class testpublic static void swap(ref int x, ref int y)int temp = x;x = y;y = temp;public static bool sortarray(int array)for(int i=array.GetUpperBound(0);i=0;i-)for (int j = 0; j = i; j+)if (arrayj = arrayi)swap(ref arrayj, ref arrayi);return true;,

39、58,class Programpublic delegate bool dlsort(int x);static void Main(string args)int arr = new int 8, 9, 5, 7, 4, 3, 1, 2 ;dlsort mydl;mydl = new dlsort(test.sortarray);mydl(arr);foreach (int i in arr)Console.Write(“0 “, i);Console.ReadKey();,59,多路广播委托,前面使用的委托只包含一个方法调用。调用委托的次数与调用方法的次数相同。如果要调用多个方法,就需要

40、多次显示调用这个委托。其实委托也可以包含多个方法,这种委托就是多路广播委托。 多路广播委托派生于System.MulticastDelegate,它的Combine方法允许把多个方法调用链接在一起,我们可以通过+=来向委托添加调用方法,也可以用-=删除其中的调用方法。,60,class testpublic static void MultiplyBy2(double value)double result = value * 2;Console.WriteLine(“Multiplying by 2: 0 gives 1“, value, result);public static void

41、 Squre(double value)double result = value * value;Console.WriteLine(“Squaring: 0 gives 1“, value, result);,class Programdelegate void MathsOp(double x);static void Main(string args)MathsOp operation = new MathsOp(test.MultiplyBy2);operation += new MathsOp(test.Squre);double x = 30;operation(x);opera

42、tion -= new MathsOp(test.MultiplyBy2);operation(x);,61,索引器,索引器类似于属性,不同之处在于他们的访问器采用参数。索引器主要用于封装内部集合或数组的类中。索引器可以根据需要设定不同的检索方式快速查找类或结构的实例。 索引器的声明使用this关键字,格式如下:,public int this数据类型 索引名称 /声明索引器/get和set属性访问器,62,class Daycollectionsstring days = “Sun“, “Mon“, “Tues“, “Wen“, “Thurs“, “Fri“, “Sat“ ;private

43、int GetDay(string testday)int i = 0;foreach (string day in days)if (day = testday) return i;i+;return -1;public int thisstring dayget return (GetDay(day); ,索引器举例2-1,63,索引器举例2-2,class Programstatic void Main(string args)Daycollections week = new Daycollections();Console.WriteLine(week“Fri“);Console.W

44、riteLine(week“Sun“);Console.WriteLine(week“Invalid Day“);,64,事件,类或对象可以通过事件向其他类或对象通知所发生的相关事情。发送事件的类称为“发行者”,接受事件的类称为“订阅者”。 发行者确定何时引发事件,订阅者确定执行何种操作来响应该事件。一个事件可以有多个订阅者。 使用加法赋值运算符“+=”来为某事件附加事件处理程序。可以使用减法赋值运算符“-=”取消订阅事件。,65,定义事件,访问修饰符 event 委托名 事件名;,语法,public delegate void delegateMe(); private event dele

45、gateMe eventMe;,66,订阅事件,eventMe += new delegateMe(objA.Method); eventMe += new delegateMe(objB.Method);,67,通知订阅对象,if(condition) eventMe();,调用订阅特定事件的对象的所有委托,68,演示:示例 4,示例,class TestEvents STAThreadstatic void Main(string args)/ 委托的对象Delegate objDelegate = new Delegate();/ ClassA 的对象ClassA objClassA =

46、 new ClassA();/ ClassB 的对象ClassB objClassB = new ClassB();/ 订阅该事件objDelegate.NotifyEveryOne += new Delegate.MeDelegate(objClassA.DispMethod);objDelegate.NotifyEveryOne += new Delegate.MeDelegate(objClassB.DispMethod);objDelegate.Notify(); ,class Delegate / 定义委托public delegate void MeDelegate();/ 定义事

47、件public event MeDelegate NotifyEveryOne;public void Notify()/ 如果事件不为 nullif(NotifyEveryOne != null)Console.WriteLine(“触发事件:“);/ 触发事件NotifyEveryOne(); ,class ClassA public void DispMethod()Console.WriteLine(“Class A 已接到 NotifyEveryOne 事件的通知!“); / 第二个类 class ClassB public void DispMethod()Console.WriteLine(“Class B 已接到 NotifyEveryOne 事件的通知! “); ,69,class Heaterprivate int temperature;public delegate void Boilhandler(int param);public event Boilhandler BoilEvent;public void BoilWater()for (int i = 0; i 96)if (BoilEvent != null) BoilEvent(temperature); ,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报