2022年第二章面向对象程序设计 .pdf
1 / 11 第二章面向对象程序设计(I )1、教案目的 : (1)了解面向对象的基本思想;(2)掌握类、对象的基本概念;(3)了解面向对象的基本特征;(4)掌握类的定义、对象的访问方法及访问控制;(5)掌握类的构造函数和析构函数、类的属性、类的静态成员。2、教案重难点:(1)掌握类的定义、对象的访问方法及访问控制;(2)掌握类的构造函数和析构函数、类的属性、类的静态成员;3、教案方法:讲授及练习相结合,结合多媒体广播软件演示4、教案工具:计算机,网络,多媒体广播软件5、教案学时:2 学时6、教案过程:6.1引入 ( 约 5 分钟) 复习旧课,引入新课面向对象是软件开发中的一种新思想,这种思想的引入,使我们的程序设计更加符后现实。面向对象编程主要思想是将数据以及处理这些数据的相应方法封装到类中,使用类创建的实例称为对象。类类型支持继承,派生的类可以对基类进行扩展和特殊化。面向对象的重要目标就是创建可以让不同开发者反复调用的模块,这些模块的设计易于修改、更新和扩展,通过共享和可重用的特性减少了开发和维护的成本。C#.NET 是一种面向对象的程序设计语言,它支持面向对象程序设计的许多新特性。整个C#的类模型是建立在.NET 对象的基础上的,对象模型是基础框架的一部分,而不再是编程语言的一部分,它解决了编程技巧带来的问题。6.2教案内容2.1 面向对象的基本思想 (约 15分钟)1对象的基本概念2类3面向对象的基本特征(1)封装性精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 1 页,共 11 页2 / 11 (2)继承性 (inheritance) (3)多态性2.2 类与对象(约 65分钟)2.2.1 类的定义(约 10分钟)2.2.2 对象的访问方法及访问控制(约 15分钟)(1)对象的访问方法(2)成员的访问控制2.2.3 类的构造函数和析构函数(约 15分钟)(1)构造函数(2)析构函数2.2.4 类的属性(约 10分钟)2.2.5 类的静态成员(约 15分钟)6.3小结:(约 5 分钟)(1)面向对象的基本思想;(2)类、对象的基本概念;(3)面向对象的基本特征;(4)类的定义(5)对象的访问方法及访问控制;(6)掌握类的构造函数和析构函数、类的属性、类的静态成员。6.4作业:(1)调试教材上的实例(2)阅读课件(3)完成书后的习题 (一)和(二): 1-2 7、后记:8、讲义:第二章 面向对象程序设计面向对象是软件开发中的一种新思想,这种思想的引入,使我们的程序设精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 11 页3 / 11 计更加符后现实。面向对象编程主要思想是将数据以及处理这些数据的相应方法封装到类中,使用类创建的实例称为对象。类类型支持继承,派生的类可以对基类进行扩展和特殊化。面向对象的重要目标就是创建可以让不同开发者反复调用的模块,这些模块的设计易于修改、更新和扩展,通过共享和可重用的特性减少了开发和维护的成本。C#.NET 是一种面向对象的程序设计语言,它支持面向对象程序设计的许多新特性。整个C#的类模型是建立在.NET 对象的基础上的,对象模型是基础框架的一部分,而不再是编程语言的一部分,它解决了编程技巧带来的问题。2.1 面向对象的基本思想面向对象是一种新兴的程序设计方法(一种新的程序设计规范)。基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计;从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。1对象的基本概念对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。2类把众多的事物归纳、划分成一些类是人类在认识客观世界时经常采用的思维方法。分类的原则是抽象。类是具有相同属性和服务的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。3面向对象的基本特征(1)封装性封装是一种信息隐蔽技术,用户只能看到对象封装界面上的信息,对象内部对用户是隐藏的。封装的目的在于将对象的使用者和设计者分开,使用者不必知道行为实现的细节,只需用设计者提供的消息来访问该对象。(2)继承性 (inheritance) 为了提高软件模块的可复用性和可扩充性,以便提高软件的开发效率,我们总是希望能够利用前人或自己以前的开发成果,同时又希望在自己的开发过程中能够有足够的灵活性,不拘泥于复用的模块。今天,任何面向对象的程序设计语言都必须提供两个重要的特性:继承性(inheritance) 和多态性(polymorphism) 。(3)多态性所谓多态即一个名字可具有多种语义。在大多数面向对象的语言中,如果类 P 是子类 S 的父类,则子类S 的对象s 可以用在父类P的对象p 使用的地方,这就意味着一个公共的消息集可以送到类P 和类S 对象上。当同样的消息可以被送到一个父类的对象和其子类的对象上时,这被称作多态性(polymophism )。2.2 类与对象类和对象是面向对象的程序设计语言的核心和本质。类实际上定义了一种崭新的数据类型。定义了类之后,就可以使用这种新的数据类型创建对象。类是对象的模板,对象是类的实例。使用类的好处在于,它有利于程序的模块化设计和开发,可以隐藏内部的实现细节,并能增强程序代码的精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 11 页4 / 11 重用性。2.2.1 类的定义(1)类的定义格式如下:class 类名 成员变量。成员方法。 。 例如: class A int x 。/成员变量 int f() /成员方法 return x 。 类的成员:成员变量(字段)和成员方法(函数)成员方法(函数):一般的成员方法、构造函数、析构函数类中还可以包含一种特殊的成员,称为属性,它既可看作是成员变量,也可看作是成员方法。(2)声明对象和创建对象的语法格式分别如下:类名 对象名。 /声明对象对象名 = new 类名 ()。 /创建对象也可以在声明的同时创建对象:类名 对象名 = new 类名 ()。利用类 A 来创建对象a:A a。a = new A() 。上述代码等价于:A a = new A() 。2.2.2 对象的访问方法及访问控制(1)对象的访问方法对象被声明并创建以后就可以访问对象中提供的成员了,访问对象成员的方法是通过使用”.”运算符来实现的。访问格式如下:对象名 .对象成员。例如:class B public int x 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 4 页,共 11 页5 / 11 public int f() return x+100 。 利用类 B 来声明并创建对象b:B b = new B() 。访问 b 中的成员:b.x = 100。int y = b.f() 。Console.WriteLine(y = 0,y)。结果输出:y = 200 2.2.2 对象的访问方法及访问控制(2)成员的访问控制类的成员分类常量:表示与该类相关联的常量值。字段:该类的变量。类型:用于表示一些类型,它们是该类的局部类型。方法:用于实现可由该类执行的计算和操作。属性:用于定义一些命名特性,通过它来读取和写入相关的特性。事件:用于定义可由该类生成的通知。索引器:使该类的实例可按与数组相同的(语法)方式进行索引。运算符:用于定义表达式运算符,通过它对该类的实例进行运算。实例构造函数:用于规定在初始化该类的实例时需要做些什么。析构函数:用于规定在永久地放弃该类的一个实例之前需要做些什么。静态构造函数:用于规定在初始化该类自身时需要做些什么。访问控制是通过在类成员前冠以修饰符来实现:访问控制修饰符修饰符说明new 仅允许在嵌套类定义时使用,以表明类中隐藏了由基类中继承而来的、与基类中同名的成员public 用这种修饰符修饰的成员称为公有成员。公有成员允许该类和其他类中的所有成员访问。protected 用这种修饰符修饰的成员称为保护成员。保护成员可以被该类和其派生类中的成员访问,而其他类中的成员则不允许访问。internal 只有其所在类才能访问private 用这种修饰符修饰的成员称为私有成员。私有成员只能被该类中的其他成员访问,其他类(包括派生类)中的成员是不允许直接访问的。 C#中 private是默认的修饰符。abstract 抽象类,不允许建立类的实例sealed 密封类,不允许被继承protected 用该修饰符修饰的成员只能被程序集内的类的成员及这些类的派生精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 5 页,共 11 页6 / 11 internal 类中的成员所访问。成员访问控制的例子:/首先定义类A,然后定义类B,它继承类A class A /类 A private int x 。 /私有成员 protected int y 。 /保护成员 public int z 。 /公有成员 void f() x = 1 。 /正确,允许访问本类中的私有成员 y = 2。 /正确,允许访问本类中的保护成员 z = 3。 /正确,允许访问本类中的公有成员 class B : A / 类 B,它继承类A void g() base.x = 100。 /错误,不允许访问基类中的私有成员 base.y = 200。 /正确,允许访问基类中的保护成员 base.z = 300。 /正确,允许访问基类中的公有成员 /在 Main 函数中实例化类A,并调用相关成员static void Main(string args) A a = new A() 。 a.x = 1000。 /错误,不允许访问其他类对象中的私有成员 a.y = 2000。 /错误,不允许访问其他类对象中的保护成员 a.z = 3000。 /正确,允许访问其他类对象中的公有成员 【例1】 在一个控制台应用程序中编写一个学生类student,该类包含学号(no)、姓名( name)和成绩( grade)等成员变量,并提供对这些变量成员进行赋值和读取这些成员变量的成员方法。 class student /成员变量 int no 。 string name。 double grade。 /成员方法 public int getNo() return no。 public string getName() return name 。 public double getGrade() return grade 。 public void setNo(int no) this.no = no。 public void setName(string name) this.name = name 。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 6 页,共 11 页7 / 11 public void setGrade(double grade) this.grade = grade 。 private 是默认的修饰符,故这些成员变量实际上是私有成员。static void Main(string args) student st = new student()。 st.setNo(100)。 st.setName(王智高 )。 st.setGrade(92.5)。 Console.WriteLine( 学号姓名成绩 )。 Console.WriteLine( 0 1 2, st.getNo(), st.getName(), st.getGrade() 。 Console.ReadLine() 。 2.2.3 类的构造函数和析构函数构造函数是在运用类来创建对象时首先被自动执行的方法成员,而且仅被执行一次,它通常用于对成员变量进行初始化。析构函数则是在对象被撤销(从内存中消除)时被执行,显然也仅仅执行一次,通常用于做对象被销毁前的“扫尾”工作。(1)构造函数构造函数的定义格式如下:public 类名 (参数列表 ) 语句序列 说明:构造函数的名称必须与类名同名,构造函数不允许有返回类型,要使用public 修饰符修饰,否则在非派生类中不能调用它来创建对象。构造函数可以带参数,也可以不带参数,要根据实际情况来决定。构造函数可以重载,即可以定义多个构造函数,它们函数名都与类名相同,不同的是各自的参数个数和参数类型不一样。在定义类时,如果没有显式定义构造函数,则实例化对象时会自动调用默认的构造函数。如果一旦定义了构造函数,则默认构造函数不会被调用。默认构造函数的作用是将对象成员的初始值设置为默认的值,如数值类型变量初始化为0,字符串型变量被初始化为null(空值),字符类型变量被初始化为空格等。构造函数不能被其他成员显式调用,而是在创建对象时由系统自动调用。【例 2】 使用默认构造函数的例子。下面定义了类B1,其中并没有显式定义构造函数:class B1 int x 。 string s。 char c。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 7 页,共 11 页8 / 11 public void outmembers() Console.WriteLine(x = 0, s = x1x, c = x2x, x, s, c)。 方法 outmembers 用于输出各变量的初始值B1 b1 = new B1() 。 /调用默认构造函数创建对象b1 b1.outmembers()。【例 3】 定义多个构造函数(重载),并分别调用它们创建对象。class B2 int x 。 string s。 char c。 public void outmembers() Console.WriteLine(x = 0, s = 1, c = 2, x, s, c)。 public B2() / 第 1个构造函数 public B2(int x) this.x = x。 / 第 2 个构造函数 public B2(int x, string s) this.x = x。 this.s = s。 / 第 3个构造函数 public B2(int x, string s, char c) this.x = x。 this.s = s。 this.c = c 。 / 第 4个构造函数 B2 b21 = new B2() 。 /调用第 1 个构造函数b21.outmembers()。B2 b22 = new B2(100) 。 /调用第 2 个构造函数b22.outmembers()。B2 b23 = new B2(100, 中国人 )。 /调用第 3个构造函数b23.outmembers()。B2 b24 = new B2(100, 中国人 , 男)。 /调用第 4 个构造函数b23.outmembers()。(2)析构函数析构函数的定义格式如下:类名 () 语句序列 说明:析构函数名是在类名前加上符号“”而得到。析构函数没有参数、返回类型和修饰符。一个类中至多有一个析构函数,如果没有定义析构函数,则系统会在撤销对象时自动调用默认析构函数。析构函数也不能显式被调用,而是在撤销对象时由系统自动调用。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 8 页,共 11 页9 / 11 为类 B2 定义如下的析构函数:B2() Console.WriteLine( 正在执行析构函数.)。 这样,在执行例3 中的代码时,在程序运行界面消失的前一刻会看到析构函数的执行结果:2.2.4 类的属性属性是一种特殊的类成员,它既可以被视为一种成员变量,也可以看作是一种成员方法。属性定义的语法格式如下:数据类型属性名 get return 表达式 1。 set 表达式 2。 /表达式 2 一般包含特殊变量value 例如,在类A 中添加一个名为attx 的属性:class A private int x 。 /私有成员变量 public int attx / 定义属性(可读、可写) get /可读 return x 。 set /可写 x = value 。 /value 是一种特殊的变量,用于接收对属性赋的值 通过属性attx 对私有成员变量x 进行读写操作:A a = new A() 。A.attx = 100 。/写属性Console.WriteLine(x = 0,a.attx)。 /读属性精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 9 页,共 11 页10 / 11 例如,在类A 中添加一个名为attx 的属性:class A private int x 。 /私有成员变量 public int attx / 定义属性 get /可读 return x 。 set /可写 x = value 。 /value 是一种特殊的变量,用于接收对属性赋的值 2.2.5 类的静态成员非静态方法可以访问类中包括静态方法在内的所有成员,而静态方法只能访问类中的静态成员。类的成员还可以分为静态成员和非静态成员。使用了static 修饰符的方法为静态成员,反之则是实例成员。静态成员隶属于类,只有一个版本,所有对象都共享这个版本;非静态成员隶属于对象,不同的对象(同一个类实例化)有不同的非静态成员,因此有多个版本。从内存管理的角度看,静态成员是在一个共享的内存空间中定义,所有对象都可以访问这个空间中的同一个静态成员;而非静态成员在对象被创建时形成自己的存储空间(这个空间是对象所拥有空间的一部分),这样不同的对象将形成不同的非静态成员(虽然它们的类型都一样)。从访问的方式看,静态成员不需要(也不能)实例化,只要定义类了以后就可以通过类名来访问它;而非静态成员则需要在创建对象以后通过对象名来访问。声明静态成员是由修饰符static 来完成,例如:private static int y 。 /静态成员变量public static void f(int x) /静态成员方法【例 4】 静态成员与非静态成员的区别。 class StaticCl private string objName 。 private int x 。/非静态成员变量 private static int stx 。/静态成员变量 public void setx(int x) /非静态成员方法精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 11 页11 / 11 this.x = x 。 public static void setstx(int y) /静态成员方法 stx = y 。 /在静态成员方法中不能使用关键字this public void show() /非静态成员方法 Console.WriteLine( 对象 0 : x = 1, stx = 2 , this.objName, x, stx)。 public StaticCl(string objName) this.objName = objName。 x = 0。 stx = 0。 static void Main(string args) StaticCl c1 = new StaticCl(c1)。 StaticCl c2 = new StaticCl(c2)。 c1.setx(1)。 StaticCl.setstx(2) 。 /不能写成 c1.setstx(2)。 c2.setx(3)。StaticCl.setstx(4) 。 /不能写成 c2.setstx(4)。 c1.show()。 c2.show()。 Console.ReadLine() 。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 11 页,共 11 页