Prev: C++Ⅳ:函数
Next: C++Ⅵ:再谈类
1 什么是对象
1.1 什么是对象
[ruby=Object Oriented Programming]面向对象编程[/ruby]是一种旨在使编程与现实世界更贴切的编程方式。 在编程中,[ruby=objects]对象[/ruby]是独立的单元,每一个对象都有不同的[ruby=identity]标识[/ruby],正如现实中的对象(物体)。 一个苹果是对象;一个马克杯也是。每个物体都有不同的标识。你可以有两个看起来完全一样的杯子,但它们仍然是独立且不同的物体。 Part题: 对象有: A. 标识 B. 梦想 C. 一只手 |
1.2 对象(一)
一个对象可能会包含其他的对象,但它们仍然是不同的对象。 对象也有能用于描述它们的[ruby=characteristics]特性[/ruby]。举例,车可能是红色或蓝色,杯子可能是满的或空的,等等。这些特性,也叫做[ruby=attributes]属性[/ruby]。属性描述了一个对象的目前[ruby=states]状态[/ruby]。 对象可以有多个属性(杯子可以是红色、大的、空的)。 一个对象的状态与其类型不同;一个杯子可能是装满水的,另一个杯子可能是空的。 Part题: 属性描述了: A .对象的意义 B. 对象的目前状态 C. 对象的名称 |
1.3 对象(二)
现实世界中,每个物体的行为都不同。车可以移动,手机可以响铃等等。对对象来说也一样——行为与类型相关。所以,下面的三个角度在面向对象编程语言中能用来描述任何对象:标识、属性、[ruby=behavior]行为[/ruby]。 Part题: 面向对象编程语言中的对象能用哪三样东西表示? A. 标识 属性 行为 B. 力量 忠诚 标识 C. 仅属性 |
1.4 对象(三)
在编程中,对象是[ruby=self-contained]自包含[/ruby]的,有自己的标识。它与其他对象是分开的。 每个对象都有自己的属性,描述它当前的状态。每个对象也有自己的行为,描述了它们能做什么。 计算中,对象不总是表示一个真实物体。 举个例,一个编程对象可以表示日期、时间或是银行帐户。银行帐户是无形的;你看不见也摸不到,但它仍然是一个明确的对象——有自己的标识、属性和行为。 接着来看C++中的面向对象编程(OOP)! Part题: 关于对象,下面哪两种描述是正确的? A. 对象不总是可见的东西 B. 对象总是可见的东西 C. 对象总是实物 D. 对象不总是实物 |
2 什么是类
2.1 什么是类
对象由[ruby=class]类[/ruby]创建,类也是OOP的关键部分。 类描述了对象会成为什么,但与对象本身是分开的。 换句话说,类可以想成对象的蓝图,描述,或定义。 你可以用一个类作为蓝图创建许多不同的对象。例如,在准备新建大楼时,建筑设计师会先创建一个蓝图,当作要实际建造的大楼的蓝图。一张蓝图能用来建造很多幢大楼。 编程的思路与此类似。我们先定义一个类,作为创建对象的蓝图。 每个类都有其名称,并描述了属性和行为。 编程中,词语“[ruby=type]类型[/ruby]”指一个类的名称:我们创建的对象是有其类型的。 [ruby=attributes]属性[/ruby]也常被叫做properties或[ruby=data]数据[/ruby]。 Part题: 关于类,哪条表述是正确的? A. 类只描述对象的属性 B. 类无名称 C. 类有名称,并描述了对象的属性和行为 |
2.2 方法
[ruby=Method]方法[/ruby]是另一个用于类的行为的词语。方法基本上就是属于一个类的函数。方法与函数类似——它们是能被调用的代码块,可以执行某个行为并返回值。 Part题: 方法是? A. 方法是在类中声明的函数 B. 方法是程序的主函数 C. 方法是对象 |
2.3 类的例子
举例,如果我们要创建一个银行程序,那可以给我们的类下面的特性: 名称:[ruby=银行帐户]BankAccount[/ruby] 属性:[ruby=帐户号码]accountNumber[/ruby],[ruby=余额]balance[/ruby],[ruby=开户日期]dateOpened[/ruby] 行为:[ruby=打开]open[/ruby](),[ruby=关闭]close[/ruby](),[ruby=存款]deposit[/ruby]() 类定义每个对象该有的属性和行为。但它并不指定实际的数据是什么;它只提供定义。 当我们写好类后,就可以接着来基于类创建对象。每个对象都叫做类的[ruby=instance]实例[/ruby]。创建类的过程叫做[ruby=instantiation]实例化[/ruby]。 每个对象都有自己的标识、数据和行为。 Part题: 创建对象的过程叫做... A. 实例化 B. 对象化 C. 创建 |
3 类的例子
3.1 声明类(一)
用class关键词开始你的类定义。关键字后跟着类名和类体,包装在花括号内。 下面的代码定义了一个叫做BankAccount的类:
类定义后必须有分号。 Part题: 用于定义类的关键字是? |
3.2 声明类(二)
在类体的花括号内定义类所具有的所有属性和行为(或叫做成员)。 你也可以给类的成员定义[ruby=access specifier]访问修饰符[/ruby]。 一个用[ruby=公有]public[/ruby]关键字定义的成员,在类的对象的范围内,可以在类之外访问。 你也可以将类成员指定为[ruby=私有]private[/ruby]或[ruby=受保护]protected[/ruby]。这些东西会在后面讨论细节。 Part题: public关键字是什么? A. 什么都不是 B. 一个可以访问的数据 C. 一种访问修饰符 |
3.3 创建类
让我们创建一个有一个公有方法的类,并让其输出"Hi"。
下一步是实例化一个我们的BankAccount类的对象。如定义某类型的变量一样,但我们对象的类型会是BankAccount。
我们名为test的对象有类定义的所有成员。 注意到用来访问并调用对象方法的点分隔符 (.)。 在使用类前必须先定义,正如我们使用函数一样。 Part题: 填空声明一个类MyClass,有一个公有函数名为someFunction,其向屏幕输出"hi from MyClass"。
|
4 抽象化
4.1 抽象化(一)
数据的[ruby=abstraction]抽象化[/ruby]是只向外界提供必要信息的概念。这是一种只表示本质内容而不包括实现细节的过程。 一个好的现实例子是书:你听到词语“书”时,你不知道具体的细节,例如页数、颜色、大小,但你知道书的概念——书的抽象化。 抽象化的概念是我们关注对象共有的本质,而不关心某个个例有什么特性。 Part题: 抽象化是什么意思? A. 没有意思 B. 一种对象类型 C. 关注某事的本质 |
4.2 抽象化(二)
抽象化意味着,我们可以有一个想法或概念,它不与任何具体的实例相关。 这是面向对象编程的核心构成之一。 举例,当你使用cout时,你其实使用的是ostream类的cout对象。它以流的方式处理数据,最后得到标准输出。
在这个例子中,不必知道cout是如何将文字输出到屏幕的。要使用它,你只需知道公共接口。 Part题: 下面哪条关于抽象化的表述是正确的? A. 我们可以有一个独立于任何具体实例的概念 B. 抽象化与面向对象编程无关 C. 抽象化是一种给类定义函数的方式 |
4.3 抽象化(三)
抽象化允许我们只写一个银行帐户类,然后基于类为不同帐户创建不同对象,而非为每个帐户都新建一个单独的类。抽象化是其他面向对象基础的基础,例如[ruby=inheritance]继承[/ruby]和[ruby=polymorphism]多态[/ruby]。这些都放在以后的课讲。 Part题: 什么是其他面向对象基础,例如继承和多态,的基础? |
5 封装
5.1 封装(一)
词语[ruby=encapsulation]封装[/ruby]的一部分含义是将一个实体“包裹”起来,不仅仅是为了将里面的内容整合在一起,也是为了保护它。 在面向对象中,封装不仅仅意味着简单地将属性和行为装在一个类中;也意味着将访问限制在类里。 这里的核心思想是一个对象只暴露出其他部分程序所必需来有效运行应用程序的部分。其他所有东西都对外不可见。 这被叫做[ruby=data hiding]数据隐藏[/ruby]。 Part题: 封装允许你: A. 声明一个函数 B. 隐藏类的实现细节 C. 将值赋给变量 |
5.2 封装(二)
用我们的BankAccount类举例,我们不想让程序其他部分不通过deposit()或[ruby=取款]withdraw[/ruby]()行为就访问并修改任何对象的balance。 我们应该隐藏那个属性,控制它的访问,所以它只能被对象自己访问。 这样的话,balance不能直接被对象外界改变,只能通过对象的方法来访问。 这也叫做“[ruby=black boxing]黑箱化[/ruby]”,指关闭对象的工作区,只开放我们想让它开放的部分。 这让我们可以改变方法的属性和行为,而不用改变整个程序。举例,我们可以之后回来修改balance属性的数据类型。 总结,封装的好处有: Part题: 封装的思想是(选择两项): A. 隐藏对象的一切,只暴露必要的 B. 封装对象的属性和方法 C. 为类的用户提供函数 D. 创建类的实例 |
6 封装的例子
6.1 访问修饰符(一)
访问修饰符用于给特定的类成员设置访问等级。 三级访问修饰符分别是public,protected和private。 一个公有成员可以在类之外,以及在类对象的范围内访问。 举例:
name属性是公有的;它可以在外部代码访问。 访问修饰符只需声明一次;多个成员可以跟在一个访问修饰符后面。 Part题: 填空声明一个类MyClass,有一个数据成员,类型string名为myData,之后在main中给它赋值"I love C++"。别忘记包含string数据类型需要的头文件。
|
6.2 私有
一个私有成员不能被类的外界访问或甚至看见;它只能在类的内部访问。 一个公有成员函数可以用于访问私有成员。举例:
name属性是私有的,在外界无法访问。 公有setName()方法用于设置name属性。 如果没有定义访问修饰符,类的所有成员都默认设为私有。 Part题: 填空声明一个类MyClass,有一个私有数据成员,类型int名为myData。声明一个公有函数setMyData(),设置myData的值为它的参数。
|
6.3 访问修饰符(二)
我们可以添加另一个用于获取属性的值的公有方法。
getName()方法返回私有的name属性的值。 Part题: 填空声明一个获取MyClass类数据成员myData的方法。myData的获取方法是一个名为getMyData(),返回myData值的公有函数。
|
6.4 访问修饰符(三)
组合起来:
我们通过封装向外部代码隐藏name属性。然后我们通过公有方法提供对它的访问。我们类的数据只能通过这些方法读取和修改。 这允许改变方法和属性的实现,而不影响外界代码。 Part题: 填空声明一个MyClass对象,设置它的数据成员的值为14,之后输出其值到屏幕。用公有函数setMyData和getMyData完成上述操作。
|
7 构造函数
7.1 构造函数(一)
类的[ruby=constructor]构造函数[/ruby]是类的特殊成员函数。它们在当新的类对象创建时执行。 构造函数的名称与类名一致。它们没有返回类型,就连void也没有。 举例:
现在,在创建myClass类型的对象时,构造函数被自动调用。 Part题: 构造函数什么时候调用? A. 当类对象被创建 B. 永远不 C. 当类被声明 |
7.2 构造函数(二)
构造函数在为某些成员变量设置初始值时非常有用。 默认的构造函数没有参数。但当需要时,可以给构造函数加参数。这使你可以在创建对象时给它赋初值,如下例所示:
我们定义了一个构造函数,接受一个变量,并通过setName()方法赋给name属性。 Part题: 填空声明一个有构造函数的类my_class。
|
7.3 构造函数(三)
创建对象时,你现在需要向构造函数传参,与调用函数时一样:
我们定义了两个对象,通过构造函数给每个对象的name属性赋初值。 构造函数可以重载。 Part题: 填空声明有构造函数的类MyClass。在main函数中创建一个MyClass对象并传递14作为构造函数参数。
|
期末考试
1. 哪条表述正确? A. 对象是类的实例 B. 对象是类的函数 C. 对象是类的抽象 2. 用于描述面向对象编程中的对象的三个词分别是属性、行为和? 3. 一个类能有多少函数(方法)? A. 一 B. 二 C. 任意 4. public和private关键字叫做? A. 类函数 B. 访问修饰符 C. 数据成员 5. 填空声明类Student,有一个名hello的公有函数。hello()函数输出"hi from student"到屏幕。
6. 填空声明类Student,有一个int类型的数据成员age。Student类有一个一参构造函数,其设置age数据成员的值。
|