第五讲:类的成员、对象成员的引用
- 格式:doc
- 大小:44.50 KB
- 文档页数:7
什么是⾯向对象、对象是什么、什么是类、如何使⽤对象、类和对象的关系⾯向对象⼀、⾯向对象 概念:⾯向对象是⼀种编程思想,使⽤编程语⾔解决现实问题的⼀种思路。
分类: ⾯向过程: C 语⾔ ⾯向对象: Java ⾯向对象的思想: ⾯向对象的思想: ⾯向过程的思想:⾃顶向下 逐步执⾏。
---> 当解决⼀件事情的时候,⾸先想到的是我该怎么去做⾯向对象思想:以对象为中⼼,使⽤对象调⽤其功能。
---> 当解决⼀件事情的时候,⾸先想到的是我该让谁帮我做。
想到的谁 ---> 对象 对象:现实⽣活中存在的真实的事物都是对象,Java 中有⼀句名⾔: 万物皆对象,⼤到宇宙、⼩到夸克在Java 的世界中都可以看成对象。
提起对象,就需要提起另⼀个概念——类。
类是对象的模板,对象是类的实例。
⼆、类 概念: 将具有相同特征的⼀类事物的共性进⾏抽取(抽取的过程叫做抽象),形成的⼀个概念叫做类。
类的抽象: 1. 怎么去描述⼀个事物,从哪些维度进⾏描述? 这个事物具有什么 ---> 属性 这个事物会做什么 ---> ⾏为 2. 怎么去描述⼀类事物的共性? 这些事物具有什么 ---> 属性 这些事物会做什么 ---> ⾏为 类和对象的关系: 类是对象的模板 对象是类的实例 类的定义: 概述: 属性 : 使⽤成员变量来进⾏描述 ⾏为 : 使⽤成员⽅法进⾏描述 语法:关键词:class语法:public class 类名{} 成员变量 定义位置:类中⽅法外 语法: 数据类型 变量名; / 数据类型 变量名 = 初始值;作⽤域:⾄少在本类 默认值: 和数组元素的默认值是⼀样的 基本数据类型 整数类型 0 ⼩数类型 0.0 字符类型空字符 布尔类型 false 引⽤数据类型 null 定义的注意事项 1. 在同⼀个类中不能定义两个同名的成员变量 2. 在同⼀个类中成员变量可以和局部变量可以重名,但是在访问的时候,局部变量优先。
什么是类,什么是对象,类和对象之间的关系类的概念:类是具有相同属性和服务的⼀组对象的集合。
它为属于该类的所有对象提供了统⼀的抽象描述,其内部包括属性和服务两个主要部分。
在⾯向对象的编程语⾔中,类是⼀个独⽴的程序单位,它应该有⼀个类名并包括属性说明和服务说明两个主要部分。
对象的概念:对象是系统中⽤来描述客观事物的⼀个实体,它是构成系统的⼀个基本单位。
⼀个对象由⼀组属性和对这组属性进⾏操作的⼀组服务组成。
从更抽象的⾓度来说,对象是问题域或实现域中某些事物的⼀个抽象,它反映该事物在系统中需要保存的信息和发挥的作⽤;它是⼀组属性和有权对这些属性进⾏操作的⼀组服务的封装体。
客观世界是由对象和对象之间的联系组成的。
类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,⽽对⼀类对象的抽象就是类.类描述了⼀组有相同特性(属性)和相同⾏为(⽅法)的对象。
上⾯⼤概就是它们的定义吧,也许你是刚接触⾯象对象的朋友,不要被概念的东西搞晕了,给你举个列⼦吧,如果你去中关村想买⼏台组装的PC机,到了那⾥你第⼀步要⼲什么,是不是装机的⼯程师和你坐在⼀起,按你提供的信息和你⼀起完成⼀个装机的配置单呀,这个配置单就可以想像成是类,它就是⼀张纸,但是它上⾯记录了你要买的PC机的信息,如果⽤这个配置单买10台机器,那么这10台机⼦,都是按这个配置单组成的,所以说这10台机⼦是⼀个类型的,也可以说是⼀类的。
那么什么是对象呢,类的实例化结果就是对象, ⽤这个配置单配置出来(实例化出来)的机⼦就是对象,是我们可以操作的实体, 10台机⼦, 10个对象。
每台机⼦都是独⽴的,只能说明他们是同⼀类的,对其中⼀个机做任何动作都不会影响其它9台机器,但是我对类修改,也就是在这个配置单上加⼀个或少⼀个配件,那么装出来的9个机⼦都改变了,这是类和对象的关系(类的实例化结果就是对象)。
第三章类与对象§3—1 面向对象§3—2 类的定义§3—3 对象的定义§3—4 对象的初始化§3—5 特殊类§3—6 特殊对象§3—7 特殊成员§3—8复杂对象§3—9 类类型转换§3—10 友元§3—1 面向对象一.面向对象面向对象本质上是一种自然合理的思维方法,是一种通过模仿人类建立现实世界模型的习惯思维方式和表达方式,运用对象、类、封装、继承、消息、多态性等概念来构造系统的软件开发方法,它包含面向对象的分析、设计、编程、测试和维护等过程。
它从研究的客观事物出发,将它们抽象为系统中的对象,作为构成系统的基本单位,并尽可能隐蔽对象的内部细节,再把具有相同属性和服务的对象抽象为类。
从客观事物出发,经过不同层次上的抽象得到基类和它的派生类,派生类继承基类的属性和服务,实现了共享。
类中的大多数数据只能用本类的方法进行处理,类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。
向不同对象发送同一消息,可产生不同的行为二.面向对象的三大特性1.封装性:是基础是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐藏对象的内部细节,只保留有限的对外接口使之与外部发生联系,其目的是有效地实现信息隐藏,它是软件设计模块化、软件复用、软件维护的基础对象和类是封装性的体现。
类是对若干对象的抽象描述,对象是它所属类的实例对象:是用来描述客观事物的一个实体,是问题域中客观事物的抽象表示,是用来构成系统的基本单位,由一组属性和行为构成对象属性:表示客观事物的静态特性,一般用数据表达对象行为:描述客观事物的动态特性,即事物的行为,一般用函数(方法)来表达类:是一种用户自定义的抽象数据类型,包含属性和服务两部分,它为该类的所有对象提供一种统一的抽象描述2.继承性:是关键派生类继承基类的属性和服务,派生类自身还有新的属性和服务继承机制既可避免公用代码的重复开发,减少代码和数据冗余,又可通过增强一致性来减少模块间的接口和界面继承有单继承和多继承,继承有传递性3.多态性:是补充即同一接口,多种方法;相同界面,多种实现指同一个名字对应着多种不同的行为或实现或不同对象收到相同的消息时,产生不同的行为多态性有两种:编译时的多态性:重载,包括函数和运算符重载运行时的多态性:动态联编,即同一属性或行为在基类及其各个派生类中具有不同的语义多态性使高层代码只写一次而在低层可多次复用,提高了程序设计的灵活性和效率三、基本术语1.抽象对一类具体事物共性的描述,即从一类事物中抽取共同的本质特点成为概念2.消息即成员函数的调用是向对象发出的服务请求,它包含提供服务的对象标识、服务标识以及输入信息和回答信息消息的接收者是提供服务的对象,它对外提供的每一种服务是按消息格式规定好的消息协议,该消息协议就是其服务的具体功能,即通过函数体来实现的一条完整的消息包含如下内容:①消息的接收者:对象标识②服务标识:函数名③符合消息协议要求的参数:函数实参表§3—2 类的定义一、类面向对象程序设计=对象+对象+对象对象=算法+数据结构类:是对某一类对象的抽象,它由概括了一组对象共同性质的数据和函数组成是一种用户自定义的抽象数据类型,它具有对数据的抽象性、隐藏性和封装性对象:是某一个类的实例,是对现实世界中真实对象的模拟现实世界是一个对象的世界,任何对象都具有一定的属性和操作,总能用数据结构与算法两者合一地来描述二、类的定义1.类的定义(1)说明部分用于类中成员作说明,告诉使用者“干什么”:①数据成员说明:对象的属性、状态、特征②成员函数说明:对象的行为、操作、服务、方法(2)实现部分用来实现成员函数,告诉使用者“怎么干”即提供成员函数的函数体2.具体定义格式:class 类名{public:成员函数和数据成员的说明或实现protected:成员函数和数据成员的说明或实现private:数据成员和成员函数的说明或实现};各个成员函数的实现说明:(1)类名:用户自定义的标识符,应有一定英文含义,类名本身就是类型名(2)类体:“{ }”括起来的部分,凡在其中实现的成员函数均为内联函数(3)访问权限修饰符:①public:公有访问属性,这种成员可以被任意函数访问(使用),提供类的接口功能②protected:保护访问属性,这种成员只能被本类的成员函数和友元函数以及派生类中的成员函数和友元函数访问(使用)③private:私有访问属性,这种成员只能被本类的成员函数和友元函数访问(使用)(4)当把私有成员的声明放于类体最前时,private可省略,即缺省(默认)访问权限为private(5)三种访问权限符在类体中的出现顺序可任意,也可出现多次或不出现(6)在类体中不允许对声明的数据成员进行初始化(7)在定义类的成员函数时,也可对形参设置默认值。
类成员的概念类成员是指定义在类中的变量和方法。
类是面向对象编程中一种重要的概念,它用于描述具有相似属性和行为的对象的集合。
类成员包括类变量、实例变量、类方法和实例方法。
首先,类变量是定义在类中的静态变量,它不属于任何特定的实例,而是属于整个类。
类变量可以被所有实例共享,并且它在类的所有实例之间保持一致。
类变量可以用于存储与类相关的信息,如类的常量。
其次,实例变量是定义在类中的非静态变量,每个类的实例都有自己的一组实例变量。
实例变量用于存储对象的特定属性,每个实例可以拥有不同的实例变量的值。
实例变量必须通过实例来访问,每个实例都有一份自己的实例变量副本。
然后,类方法是定义在类中的静态方法,它可以直接通过类来调用,而不需要实例化类。
类方法可以访问和修改类变量的值,但不能访问实例变量的值。
类方法常常用于执行与类相关的操作,比如创建对象或返回与类相关的信息。
最后,实例方法是定义在类中的非静态方法,它必须通过实例来调用。
每个实例方法都可以访问实例变量和类变量的值。
实例方法常常用于执行实例特定的操作,比如修改实例变量的值或执行与实例相关的计算。
在面向对象编程中,类成员的概念非常重要。
它们可以用于描述对象的属性和行为,并且可以在不同的对象之间共享。
通过使用类成员,可以更好地组织和管理代码,使得代码易于维护和扩展。
同时,类成员也方便了对象之间的通信和协作,提高了代码的可重用性。
总的来说,类成员包括类变量、实例变量、类方法和实例方法。
它们分别用于存储类相关的信息和实例特定的属性和行为。
通过使用类成员,可以更好地组织和管理代码,并提高代码的可重用性和可维护性。
类成员是面向对象编程中非常重要的概念,它们使得类能够描述和操作具有相似属性和行为的对象。
类方法和成员方法
类方法和成员方法都是面向对象编程中的方法,不同的是它们的调用方式和作用范围。
1. 类方法(class method)是定义在类中的方法,通过类名调用,而不是通过实例对象调用。
类方法可以访问静态成员和类成员,但不能直接访问实例成员。
类方法通常用于创建工厂函数或者对类的属性进行操作。
例如,在Python中定义类方法时需要使用@classmethod装饰器来标识:
python
class MyClass:
@classmethod
def my_class_method(cls, param1, param2):
pass
2. 成员方法(instance method)是定义在类中的方法,通过实例对象调用。
成员方法可以访问实例成员、静态成员和类成员。
成员方法通常用于操作实例属性或者实现类的功能。
例如,在Python中定义成员方法时不需要使用任何装饰器:
python
class MyClass:
def my_instance_method(self, param1, param2): pass
总结:
- 类方法通过类名调用,成员方法通过实例对象调用。
- 类方法只能访问静态成员和类成员,不能访问实例成员。
- 成员方法可以访问实例成员、静态成员和类成员。
第五讲:类的成员、对象成员的引用本讲基本要求掌握:类成员函数的性质、定义及存贮方式。
对象成员三种引用方式,。
理解:类函数、作用域运算符、inline成员函数的概念。
重点、难点:类成员函数的性质、定义、存贮方式及引用;对象成员三种引用方式。
一、类的成员函数(成员数据、成员函数与全局函数)(成员函数的性质、定义)1、成员函数的性质1、类的成员函数(简称类函数)是函数的一种,它也有返回值和函数类型,它与一般函数的区别只是:它是属于一个类的成员,出现在类体中。
它可以被指定为private(私有的)、public(公用的)或protected(受保护的)。
2、在使用类函数时,要注意调用它的权限(它能否被调用)以及它的作用域(函数能使用什么范围中的数据和函数)。
成员函数可以访问本类中任何成员(包括私有的和公用的),可以引用在本作用域中有效的数据。
3、一般的做法是将需要被外界调用的成员函数指定为public,它们是类的对外接口。
4、类的成员函数是类体中十分重要的部分。
如果一个类中不包含成员函数,就等同于C语言中的结构体了,体现不出类在面向对象程序设计中的作用。
2、在类外定义成员函数前面看到的成员函数是在类体中定义的。
也可以在类体中只写成员函数的声明,而在类的外面进行函数定义。
如:class Student{ public:void display(); //公用成员函数原型声明private:int num;string name;char sex; //以上 3行是私有数据成员};void Student::display() //在类外定义display类函数{ cout<<"num:"<<num<<endl;//函数体cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}Student stud1,stud2; //定义两个类对象说明:1、但成员函数在类外定义时,必须在函数名前面加上类名,予以限定(Qualifed),“::”是作用域限定符(field qualifier)或称作用域运算符,用它声明函数是属于哪个类的。
(a)Student::display();(b)没有“Student::”的限定、“::”如 ::display() 或 display()2、类函数必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函数定义之前(如上面所示的那样),否则编译时会出错。
3、在类的内部对成员函数作声明,而在类体外定义成员函数,这是程序设计的一种良好习惯。
3、inline 成员函数(类内置成员函数)类的成员函数也可以指定为内置(inline)函数。
问题提出:在类体中定义的成员函数的规模一般都很小,而系统调用函数的过程所花费的时间开销相对是比较大的。
调用一个函数的时间开销远远大于小规模函数体中全部语句的执行时间。
解决办法:为了减少时间开销,如果在类体中定义的成员函数中不包括循环等控制结构,C++系统会自动将它们作为内置(inline)函数来处理。
也就是说,在程序(对象)调用这些成员函数时,并不是真正地执行函数的调用过程(如保留返回地址等处理),而是把函数代码嵌入程序的调用点。
这样可以大大减少调用成员函数的时间开销。
(程序调用,不占对象物理内存) 定义方法:C++要求对一般的内置函数要用关键字inline声明,但对类内定义的成员函数,可以省略inline,因为这些成员函数已被隐含地指定为内置函数。
例如:class Student{ public:void display()//也可以写成: inline void display(){ cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}private:int num;string name;char sex;};注意:如果成员函数不在类体内定义,而在类体外定义,系统并不把它默认为内置(inline)函数,调用这些成员函数的过程和调用一般函数的过程是相同的。
如果想将这些成员函数指定为内置函数,应当用inline作显式声明。
例如:class Student{ public:inline void display();//声明此成员函数为内置函数Private:int num;string name;char sex;};inline void Student::display() //在类外定义display函数为内置函数 { cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}注意:1、如果在类体外定义inline函数,则必须将类定义和成员函数的定义都放在同一个头文件中(或者写在同一个源文件中),否则编译时无法进行置换(将函数代码的拷贝嵌入到函数调用点)。
但是这样做不利于类的接口与类的实现分离,不利于信息隐蔽。
虽然程序的执行效率提高了,但从软件工程质量的角度来看,这样做并不是好的办法。
2、只有在类外定义的成员函数规模很小而调用频率较高时,才将此成员函数指定为内置函数。
4、成员函数的存储方式C++编译系统为每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。
图4:一般理解图5:C++编译系统处理如果声明了一个类:class Time{ public:int hour;int minute;int sec;void set(){ cin>>a>>b>>c;}};可以用下面的语句来输出该类对象所占用的字节数:cout<<sizeof(Time)<<endl;输出的值是12。
需要注意:1、虽然调用不同对象的成员函数时都是执行同一段函数代码,但是执行结果一般是不相同的。
2、不论成员函数在类内定义还是在类外定义全局函数,函数的代码段都用同一种方式存储,即都不占用对象的存储空间。
3、不要将成员函数的这种存储方式和inline(内置)函数的概念混淆。
用inline声明的作用是在调用该函数时,将函数的代码段复制插入到函数调用点,而若不用inline声明,在调用该函数时,流程转去函数代码段的人口地址,在执行完该函数代码段后,流程返回函数调用点。
inline与成员函数是否占用对象的存储空间无关。
4、既然成员函数的代码并不放在对象的存储空间中,那么前面说的“对象studl的成员函数display”的说法是否不对呢?应当说明:常说的“某某对象的成员函数”,是从逻辑的角度而言的,而成员函数的存储方式(不存储在对象的空间内),是从物理的角度而言的,是由计算机根据优化的原则实现的,二者是不矛盾的。
物理上的实现必须保证逻辑上的实现。
例如某人有钱若干,可以放在家中,也可以放在银行中租用的保险箱中,虽然在物理的角度上保险箱并不在他家中,但保险箱是他租用的,这笔钱无疑是属于他的,这是从逻辑的角度而言的。
同样.虽然成员函数并没有放在对象的存储空间中,但从逻辑的角度,成员函数是封装在—个对象中的,所以完全可以说“调用对象studl的成员函数display”,不会引起误解。
作为程序设计人员,了解一些物理实现方面的知识是有好处的,可以加深对问题的理解。
二、对象成员的引用(包含成员函数、成员数据)在程序中经常需要访问对象中的成员。
访问对象中的成员可以有3种方法:1.通过对象名和成员运算符访问对象中的成员;2.通过指向对象的指针访问对象中的成员;3.通过对象的引用变量访问对象中的成员。
1、通过对象名和成员运算符访问对象中的成员访问对象中成员的一般形式为:对象名.成员名(包含成员函数、成员数据)说明:1、“.”是成员运算符,用来对成员进行限定,指明所访问的是哪一个对象中的成员。
2、不能只写成员名而忽略对象名,不应该这样写:num=1001; //错误。
这样写成为对象中的临时变量。
3、不仅可以在类外引用对象的公用数据成员,而且还可以调用对象的公用成员函数,但同样必须指出对象名,如 studl.display()。
4、应该注意所访问的成员是公用的(public)还是私有的(private)。
私有数据成员,不能被外界引用。
5、在类外只能调用公用的成员函数。
显然在一个类中应当至少有一个公用的成员函数,以作为类的对外接口否则程序就无法对对象进行任何操作。
2、通过指向对象的指针访问对象中的成员访问对象中成员的一般形式为:对象指针名->成员名(包含成员函数、成员数据) 或:(*对象指针名).成员名(包含成员函数、成员数据)例如:class Time{ public://数据成员是公用的int hour;int minute;};Time t,*p //定义对象t和指向Time类的指引变量PP=&T //使p指向对象tcout<<P->hour;//输出P指向的对象中的成员hour3、通过对象的引用来访问对象中的成员如果为一个对象定义了一个引用,它们是共占同一段存储单元的,实际上它们是同—个对象,只是用不同的名字表示而已。
因此完全可以通过引用来访问对象中的成员,其概念和方法与通过对象名来引用对象中的成员是相同的。
例如:如果已声明了Time类,并有以下定义语句:Time t1; //定义对象t1Time &t2=t1; //定义Time类引用变量t2,并使之初始化为tlcout<<t2.hour;//输出对象t1中的成员hour由于t2与t1共占同一段存储单元(即t2是tl的别名),因此t2.hour就是t1.hour。
三、作业1、 P67第二、三、四题。
2、实验四。