收藏 分享(赏)

第3章面向对象程序设计.ppt

上传人:hskm5268 文档编号:8026371 上传时间:2019-06-04 格式:PPT 页数:73 大小:386KB
下载 相关 举报
第3章面向对象程序设计.ppt_第1页
第1页 / 共73页
第3章面向对象程序设计.ppt_第2页
第2页 / 共73页
第3章面向对象程序设计.ppt_第3页
第3页 / 共73页
第3章面向对象程序设计.ppt_第4页
第4页 / 共73页
第3章面向对象程序设计.ppt_第5页
第5页 / 共73页
点击查看更多>>
资源描述

1、第3章 C#面向对象程序设计,学习内容与要点 类的创建与使用 类的继承与多态 接口创建与实现 泛型创建与实现 委托与事件,类和对象,类: 相对对象而言,类似于蓝图 包含方法和数据,对象: 是类的实例 使用关键字 new 创建 对象具有行为,对象,类,示例1:创建一个描绘鸭子的对象 定义一个“鸭子”类 这个“鸭子”类具有特定的行为,如行走、鸣叫、飞行和游泳。 这个类具有特定的属性,如高度、重量和颜色。 “鸭子”类定义了鸭子是什么和鸭子能做什么。一个鸭子对象一只具有特定高度、颜色、重量和行为特征的鸭子。你所饲养的鸭子就可以看做是鸭子的对象。,课堂讨论,先有对象还是先有类?,应该先定义类才可以从类的

2、定义声明对象。,定义类和创建对象,public class Customer public string name;public decimal creditLimit;public uint customerID; ,定义类,将类实例化为对象,Customer nextCustomer = new Customer();,类成员的访问,nextCustomer.name = “Suzan Fine“;,课堂讨论,要访问对象的成员应该先实例化对象吗?,需要先实例化对象。,3.1 类,在面向对象程序设计中,类被作为一种数据结构,是包含数据成员、函数成员和嵌套类型的数据结构。 类声明 属性 类修饰

3、符 class 类名类体类修饰符包括new、public、protected、internal、private、abstract和sealed。,例 定义一个Person类 using System; public class Personprivate string name;private int age; private long ID;public Person(string n, int a, long i)name = n; age = a; ID = i; public virtual void Display()Console.WriteLine(“Name : 0” , na

4、me);Console.WriteLine(“Age : 0” , age);Console.WriteLine(“ID : 0” , ID); ,创建类实例,格式为:类名 实例名 = new 类名(参数); 两种形式Person myTest = new Person();或Person myTest;myTest = new Person();,类成员,类成员分为两大类,类本身定义的成员和从基类继承来的成员。 类成员包括函数成员和数据成员。 类的成员要么是静态成员,要么是实例成员,类成员,1类成员访问修饰符 访问修饰符用于指定类成员的可访问性。 共有public、private、prote

5、cted和internal四个类成员访问修饰符。,类标识符,即类名,命名原则: 使用过名词或名词短语 使用Pascal大小写风格:类名的第一个字母和后续每个单词的首字母大写,如:BinaryTree 尽量不使用缩写 不要使用诸如C这样的类型前缀来指示类,例如,类名应该用BinaryTree,而非CBinaryTree 不要使用下划线 根据约定,接口名总是以字母I开头,因此尽量不要用I作为类名的第一个字符,除非I确实是整个单词的第一个字母。例如,IntegralCalculator。,2静态成员与实例成员,当用static修饰符声明成员时,得到静态成员,静态成员属于类,为这个类的所有实例所共享

6、不用static修饰符声明的成员,称为实例成员,实例成员被类的实例所拥有。,例 定义一个含有静态成员和一个实例成员的Student类 using System; class Studentint SNO; /实例成员,表示学生学号static int count; /静态成员,计数学生人数public Student(int s)SNO = s;count +; public void display()Console.WriteLine(“count= 0,SNO = 1“,count,SNO); class TestStudentpublic static void Main()Stude

7、nt s1= new Student(12);s1.display();Student s2 = new Student(20);s2.display(); ,构造函数和析构函数,构造函数特殊性表现在: 构造函数的名字必须与类名相同; 构造函数可以带参数,但没有返回值; 构造函数在对象定义时被自动调用;通过initializer(初始化调用),可以在输入constuctor-body(构造函数体)之前先行调用代码。 如果没有给类定义构造函数,则编译系统会自动生成一个缺省的无参数构造函数,其形式如下:public con() : base() 构造函数可以被重载,但不可以被继承。,构造函数和析构

8、函数,有三类构造函数: 1. 实例构造函数(instance)2. 私有构造函数(private,实例构造函数的一种特殊情况)3. 静态构造函数(static)构造函数不像方法,它是不能被继承的。每个类都要定义自己的构造函数,或者使用默认的无参数构造函数。,实例构造函数用于创建和初始化实例,创建新对象时要调用实例构造函数,其格式为:访问修饰符 类名(形参列表) 函数体 静态构造函数用于初始化静态数据,或用于执行仅需执行一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。其格式为:static 类名() 函数体 ,静态构造函数 其格式为:static 类名() 函数体

9、 静态构造函数,也称为类型构造函数,它在加载类型之 后及在访问任一类型成员之前执行。其主要作用是初始 化静态类成员,或用于执行仅需执行一次的特定操作。 它的作用之所以有限,原因在于与实例构造函数相比, 它多了很多限制: 它不能有参数,不能重载,因此,类只能有一个静态构造函数。 它的可访问性必须是private,这由C#自动指定。 它不能调用其他构造函数 它只能访问静态成员。 P64-2Static,析构函数主要用于释放类实例。析构函数特殊性表现在: 析构函数的名字与类名相同,但它前面加一个“”符号; 析构函数不能够带参数,也没有返回值; 当撤销对象时,自动调用析构函数; 析构函数不能被继承,也

10、不能被重载。,例 使用构造函数和析构函数 using System; class Complexdouble imag, real;public Complex() /无参数构造函数/有两个参数的构造函数public Complex(double r , double i ) imag = i;real = r; Complex() /析构函数 ,方法,方法是表现类或对象行为的成员函数。 1.方法声明 声明格式:方法修饰符 返回类型 方法名(形参列表) 方法体 修饰符包括:new、public、protected、internal、private、static、virtual、sealed、o

11、verride、abstract和extern。,2.方法参数,(1)值参数未用任何修饰符声明的参数为值参数。 (2)引用参数用ref修饰符声明的参数为引用参数。在方法中对引用参数的任何更改都会反映给实参。 (3)输出参数用out修饰符声明的参数称为输出参数。如果希望函数返回多个值,可使用输出参数。 (4) 参数数组用params修饰符声明的变量称为参数数组,它允许向函数传递个数变化的参数。,2.方法参数,(1)值参数默认情况下,方法参数是按值传递,这意味着,会把参数数据的副本(而非实际数据)传递给目标方法。由于传递的不是实际数据,因此,目标方法对这些数据副本的修改不会影响调用例程的原参数。,

12、例 使用值参数 using System; class TestValue static void Swap(int a , int b ) int t; t = a; a = b; b = t; static void Main()int x =10, y = 20;Console.WriteLine(“x = 0 , y = 1“, x , y);Swap(x , y);Console.WriteLine(“x = 0 , y = 1“, x , y);,2.方法参数,如果参数是引用类型,如类实例,则会传递对象的一个引用。这样被调用的方法就能够修改或设置参数值。C#提供了两个修饰符来指示参

13、数要按引用传递(传引用):ref和out。这两个参数的作用都能做到将参数的地址传递给目标方法。但究竟使用哪个关键字,取决于参数是由调用方法初始化,还是由被调用方法初始化。 (2)引用参数 ref若是由调用方法初始化参数值,则使用ref关键字 (3)输出参数 out当被调用方法初始化参数值时,要使用out关键字。,例 使用引用参数 using System; class TestValue static void Swap(ref int a , ref int b )int t; t = a; a = b; b = t; static void Main()int x =10, y = 20;

14、Console.WriteLine(“x = 0 , y = 1“, x , y);Swap(ref x , ref y);Console.WriteLine(“x = 0 , y = 1“, x , y); ,例 使用输出参数 using System; class TestOut static int OutMultiValue(int a , out char b)b = (char)a; return 0; static void Main() int t = 65 , r; char m;r = OutMultiValue(t ,out m);Console.WriteLine(“r

15、 = 0 , m = 1” , r , m); ,例 使用参数数组 using System; class TestParamsstatic void MutiParams(params int var)for(int i= 0 ;i var.Length ; i +)Console.WriteLine(“var0 = 1”, i , vari);static void Main()int arr = 10 , 20 ,30;MutiParams( arr ); /有3个参数,参数为一维数组MutiParams(100, 200 ); /有2个参数MutiParams(); /没有参数,3.静

16、态方法和实例方法,用static修饰符声明的方法为静态方法,它不与实例相关联,它属于类。只需要类名和方法名就可调用静态方法 未用static修饰符声明的方法为实例方法。它与特定实例相关联。可以用this来访问该实例。实例方法可以访问类中的任何成员。,例 使用静态方法和实例方法 using System; class TestMethodstatic int x; /静态数据成员int y; /非静态数据成员static void A() /静态方法Ax = 10; /正确,在静态方法中访问静态成员y = 20; /错误,在静态方法中访问非静态成员 void B()x = 10; /正确,在实例

17、方法中访问静态成员y = 20; /正确,在实例方法中访问非静态成员 static void Main()TestMethod t = new TestMethod();TestMethod.A(); /使用类名调用静态方法t.B(); /使用实例调用实例方法,4.方法重载,它允许一个类中有同名的方法存在 为了区分这些同名方法,要求方法有不同的参数,要么参数个数不同,要么参数类型不同。,例 使用方法重载 using System; class TestMethodint square(int x) return x*x; double square(double x) return x*x;

18、decimal square(decimal x)return x*x; static void Main()TestMethod t = new TestMethod();Console.WriteLine(“The squre is 0 , 1 , 2”, t.square(10), t.square(12.34) , t.square(123.456m); ,5.运算符重载,运算符重载可以对C#中已有的运算符赋予新的功能。其格式为:public static 返回值类型 operator unary-operator ( 参数列表 )方法体,例3-10 重载Point类的和运算符 usi

19、ng System; class Point private int x,y;public Point(int a, int b) x = a; y = b; public static Point operator +(Point p)p.x +; p.y +; return p; public void Display()Console.WriteLine(“Point.x = 0, Point.y = 1“,x,y); public static Point operator +(Point p1,Point p2)Point p = new Point(0,0); p.x = p1.x

20、 + p2.x; p.y = p1.y + p2.y;return p; static void Main(string args)Point a = new Point(10,20);Point b = new Point(30,40);a = a + b; a.Display();a +; a.Display(); ,6.this关键字,this 关键字引用类的当前实例,成员通过this关键字可以知道自己属于哪一个实例。this关键字是一个隐含引用,它隐含于每个类的成员函数中。 this 的常用用途: 限定被相似的名称隐藏的成员 将对象作为参数传递到其他方法 声明索引器 用this访问实例

21、方法,索引器-index,索引器是一种特殊的属性,是带有参数的属性,可以像数组和集合那样访问类。 索引器的声明类似于属性,只是把属性名称换成了this关键字,同时给属性添加了索引参数。 索引器的声明格式 修饰符 数据类型 this 索引类型 index get /获得属性的代码set /设置属性的代码 This关键字 用于定义一个索引器 Index是一个索引值,通过index可以获取或者设置指定索引的数值。 索引器也可以拥有两个以及多个参数,就像二维数组那样。索引值也不一定是一个整数类型,可根据需要自行定义。,字段与属性,1.字段 字段表示与对象或类相关联的变量。 静态字段:用static修饰

22、符声明的字段,无论存在多少个类实例,它们都共享一个静态字段拷贝。 实例字段:没用static修饰符声明的字段,类的每个实例都包含实例字段的一个拷贝。 只读字段:用readonly修饰符声明的字段,它只能在字段声明或构造函数中赋值,在其它任何地方都不能改变只读字段的值。,例 使用字段 using System; class Goods public double high;public readonly double width = 30;public static int count = 0;public Goods(double h,double w)high = h; width = w;

23、count +; static void Main(string args)Goods y = new Goods(100,200);Console.WriteLine(“high=0,width=1,count=2“ ,y.high,y.width,Goods.count);Goods z = new Goods(300,400);Console.WriteLine(“high=0,width=1,count=2“ ,z.high,z.width,Goods.count); ,2.属性,属性用于刻画对象的特征或表示对象的状态,它提供对类或对象性质的访问。 其格式为:访问修饰符 数据类型 属性

24、名get get访问器代码块 set set访问器代码块 set访问器:给属性赋值,它使用value设置属性的值 get访问器:获取属性值,它通过return返回属性的值。 如果只有get访问器,表示是只读属性;如果只有set访问器,表示只写属性;如果既有get访问器,也有set访问器,表示读写属性。,例 使用属性 class Window private double m_width = 30;public double widthget return m_width; set m_width = value; static void Main(string args)Window y =

25、new Window();y.width=200;Console.WriteLine(“The width of window is 0.“,y.width); ,惯用法 (1) 属性开头字母大写,字段开头字母小写. (2) 一般不把字段public,class Person private int age;public int Agegetreturn age;setage=value;public void SayHello()Console.WriteLine(“我的年龄是0“,Age); ,继承,父类,子类,书,继承是软件复用的一种形式。采用这种形式,可吸收现有类的数据和行为,为其赋予

26、新功能,从而创建出新类。软件复用节省了程序开发时间。它还鼓励人们重用经过实践检验和调试的高质量软件,使系统能高效地实现。,继承,继承是面向对象程序设计的一个重要特征,它允许在既有类的基础上创建新类,新类从既有类中继承类成员,而且可以重新定义或加进新的成员,从而形成类的层次或等级。 一般称被继承的类为基类或父类,而称继承后产生的类为派生类或子类。,基类和派生类,日常生活中,一个类的对象也是另一个类的对象 如,一个Rectangle(矩形)类“属于”四边形(正方形、平行四边形和梯形同样是四边形)。也可以说,Rectangle(矩形类)是从Quadrilateral(四边形)类继承而来的。 Quad

27、rilateral类是基类, Rectangle类是派生类。 再如,教师类和学生类可以由大学成员类派生,讲师、教授又可以由教师类派生,毕业生和在校生又可以由学生类派生。,C#继承有如下重要性质:,C#只允许单继承,即派生类只能有一个基类; C#的继承是可传递的,如果 C 从 B 派生,而 B 从 A 派生,那么 C 就会既继承在 B 中声明的成员,又继承在 A 中声明的成员; 派生类扩展它的直接基类,即派生类可以添加新的成员,但不能删除从基类继承的成员; 构造函数和析构函数不能被继承; 派生类可以隐藏基类的成员,如果在派生类中声明了与基类同名的新成员时,基类的该成员在派生类中就不能被访问到。,

28、1.派生类的声明,类修饰符 class 类名 :基类 类体 ,例 从声明的Person类派生一个新类Employee public class Employee : Personprivate string department;private decimal salary;public Employee(string n , int a , long i , string d , decimal s) : base(n , a , i )department = d;salary = s;public override void Display()base.Display();Console

29、.WriteLine(“Department : 0” , department);Console.WriteLine(“Salary : 0” , salary); ,2.base关键字,base关键字用于从派生类中访问基类的成员,它有两种基本用法: 指定创建派生类实例时应调用的基类构造函数,用于调用基类的构造函数完成对基类成员的初始化工作; 在派生类中访问基类成员。 注意:不能在静态方法中使用base关键字。 3.成员隐藏 在派生类中,通过声明与基类同名的新成员可以隐藏基类的成员,例 使用成员隐藏 public class Employee : Personprivate string d

30、epartment;private decimal salary;public Employee(string n , int a , long i , string d , decimal s) : base(n , a , i )department = d;salary = s; new public void Display()base.Display();Console.WriteLine(“Department : 0” , department);Console.WriteLine(“Salary : 0” , salary);,多态,多态性是指不同对象收到相同消息时,会产生不同

31、动作。从而实现“一个接口,多种方法”。 C#支持两种多态性: 编译时多态性,是在程序编译时就决定如何实现某一动作,是通过方法重载和运算符重载实现的。 是运行时多态性,是在运行时动态实现某一动作,是通过继承和虚成员实现的。,方法重载和运算符重载:要求方法名称相同,参数类型和参数个数不同。 继承和虚成员实现的虚方法重载:要求方法名称、方法参数的类型 数量 顺序、方法参数返回值类型都与基类虚方法一样。在派生类重载虚方法要加上override修饰符。,例 通过虚方法实现多态性 using System; class Basepublic void Display() Console.WriteLine

32、(“Display in Base”); public virtual void Print()Console.WriteLine(“Print in Base”); class Derived : Basenew public void Display()Console.WriteLine(“Display in Derived”);public override void Print()Console.WriteLine(“Print in Derived”); class TestVirtualstatic void Main()Base b = new Base(); Derived

33、d = new Derived();b.Print(); d.Print();b.Display(); d.Display();b = d;b.Print(); d.Print();b.Display(); d.Display(); ,抽象类,抽象类表示一种抽象的概念,用来为它的派生类提供一个公共接口。 声明类抽象类:加上abstract修饰符 抽象类只能作为其它类的基类,不能实例化。 抽象类可以包含抽象方法和抽象访问器,也可以包含实例字段和非抽象方法,例 使用抽象类 abstract class Figureprotected double x = 0 , y = 0;public Figu

34、re(double a, double b)x =a; y = b; public abstract void Area(); class Square : Figurepublic Square(double a, double b):base(a,b) public override void Area()Console.WriteLine(“The area of square is 0“,x*y); class Circle : Figurepublic Circle(double a):base(a,a) public override void Area()Console.Writ

35、eLine(“The area of circle is 0“,x*x*Math.PI ); class TestAbstract public static void Main() Square s = new Square(20,30); Circle c = new Circle(10);s.Area(); c.Area(); ,密封类,不能被继承的类,称为密封类。 声明密封类:使用sealed修饰符 例 使用密封类 sealed class SealedClasspublic double x = 0 , y = 0;public SealedClass(double a, doubl

36、e b) x =a; y = b; public void Display()Console.WriteLine(“x = 0 , y = 1”,x , y);,静态类,类中只包含静态成员 声明静态类:使用static修饰符 例 声明静态类 static class StaticClasspublic const int y=100; public static void Display(int x)Console.WriteLine(“x = 0,y=0”,x,y);,注意: 静态类既不能实例化,也不能被继承。 静态类默认继承自System.Object根类,不能显式指定任何其它基类。 静态

37、类不能有实例构造函数,系统也不会为它提供默认构造函数。但它可以包含静态构造函数。 静态类不能有任何实例成员,但可以有常量成员。 静态类不能实现任何接口。 静态类的成员不能有protected或protected internal访问保护修饰符。 静态类的成员默认并不是static类型的,必须用static修饰符显式声明成员。,例 使用静态类 class Program static void Main(string args) /正确的使用形式StaticClass.Display(200); /错误的使用形式,无法生成静态类的实例StaticClass c = new StaticClass

38、(); Console.Read(); ,分部类,使用partial 关键字声明类或结构,就可以将类的一部分放在一个文件中,而将另一部分放在另一个文件中 注意: 分部类支持类、结构和接口,但不支持委托和枚举 在分部类中,不能把同一个成员声明两次。 同一个类型的各个部分都必须包含partial修饰符。 同一个类型各个部分必须位于相同的名称空间中。 同一个类型的各个部分必须被同时编译。 如果一个类型是某个基类的派生类,则该类型的各个部分上指定的基类必须一致。,3.2 接口,接口并不提供实现。它只表示一种约定,实现接口的类或结构必须遵守该接口定义的约定。 接口声明格式:接口修饰符 interface

39、 接口名 : 基接口 接口体 ,例声明一个IShape接口public interface IShape double Area();string Type get; 注意: 接口的所有成员都被定义为公有的,使用其它修饰符是错误的; 接口不能包含常量、域; 接口不能包含构造函数、析构函数和静态成员。,接口实现 例实现IShape接口public class Rectangle : IShape private int width, height;public Rectangle(int w, int h) width = w; height = h; public double Area()

40、return width * height; public string Type get return “矩形“; ,3.3 泛型,泛型即通过参数化类型来实现在同一份代码上操作多种数据类型。 1. 泛型类 定义格式:修饰符 class 类名类体 泛型类的实例化格式为:类名 实例名=new 类名(构造函数的实参);,例堆栈泛型类 class Stack private T s;int pos;public Stack(int size) s = new Tsize; pos = 0; public void Push(T val) spos = val; pos+; public T Pop(

41、) pos-; return spos; public void Display() Console.WriteLine(“Stack Push:“);foreach (T i in s) Console.WriteLine(i); ,class Program static void Main(string args) Stack s1 = new Stack(2);s1.Push(1); s1.Push(2); s1.Display();Console.WriteLine(“Stack Pop:“);Console.WriteLine(s1.Pop();Console.WriteLine(

42、s1.Pop();Stack s2 = new Stack(2);s2.Push(“one“); s2.Push(“two“);s2.Display();Console.WriteLine(“Stack Pop:n0n1“, s2.Pop(),s2.Pop();Console.Read(); ,泛型方法,使用类型参数声明方法 例在数组中查找某个数 class Program public static int Find(T values,T val) for(int i=0;ivalues.Length;i+) if(valuesi.Equals(val) return i;return -1

43、; static void Main(string args) int val = 4;int pos = Program.Find(new int 1, 2, 3, 4, 5, 6 , val);Console.WriteLine(“Found 0 in position of 1“, val,pos); ,3.4 委托与事件,委托属于引用类型,用于封装方法(函数)的引用 使用委托的步骤: 委托声明;委托实例化;委托调用。 委托声明的格式:修饰符 delegate 返回值类型 标识符 (形参列表); 委托实例化用于创建委托实例。与类实例创建的语法相同,例 冒泡法排序 public class

44、 Sort public delegate bool Compare(int a, int b);public static void BubbleSort(int element, Compare compare) for(int i=0;i i; j-)if (compare(elementi, elementj)Swap(ref elementi, ref elementj); private static void Swap(ref int a, ref int b) int temp; temp = a; a = b; b = temp; ,class Program static

45、void Main(string args) int ElementArray = new int1023, 3, 58, 23, 90, 45, 12, 78, 25, 67;Select s = new Select();Sort.Compare cp = new Sort.Compare(s.Ascending); Sort.BubbleSort(ElementArray, cp);s.Display(ElementArray);cp += new Sort.Compare(s.Descending); Sort.BubbleSort(ElementArray, cp); s.Displ

46、ay(ElementArray); ,public class Select public bool Ascending(int x, int y) return x y; public bool Descending(int x, int y) return x y; public void Display(int e) foreach (int t in e)Console.Write(t.ToString() + t);Console.WriteLine(); ,匿名方法,不用事先定义函数,直接将代码与委托实例相关联 匿名方法实例化的格式: 委托名 实例变量 delegate(形参列表)

47、 ;,例 使用匿名方法 class Programdelegate void Message();delegate int AddOne(int v);static void Main(string args) int y = 10;AddOne ao = delegate(int val) val+;return val;Console.WriteLine(“y=0,y+=1“,y,ao(y);Message ms=delegate() Console.WriteLine (“Anonymous Method“);ms();,事件,对象之间的交互是通过消息传递来实现的,而事件就是对象发送的消

48、息,通过发信号的形式通知操作的发生。 事件声明的具体格式为:属性集 修饰符 event 委托类型 事件名;,例 使用C#事件,显示当前时间 public delegate void TimeEventHandler(string s); /委托声明 class MyTime public event TimeEventHandler Timer;/声明事件public void OnTimer(string s) if (null != Timer) Timer(s); /引发事件 class ProcessTime public void GenerateTime(string s) /事件处理 Console.WriteLine(“Hello 0!The time is 1 now“, s, DateTime.Now); class TestTime static void Main(string args) ProcessTime p = new ProcessTime();MyTime t = new MyTime(); /把事件与事件处理联系起来t.Timer += new TimeEventHandler(p.GenerateTime); t.OnTimer(“Peter“); /使用事件,

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

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

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


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

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

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