面向对象这一章,是上午题里概念最密、但最不容易失分的一章:它不考计算,考的是你能不能把“封装、继承、多态、绑定”这些词和具体场景对上号。2009 到 2021 年一共 63 道题,绝大部分是“给一句话,问这是哪个概念”。
教材开篇就给了“面向对象”的判定等式,这是本章所有概念的根:
面向对象 = 对象(Object)+ 分类(Classification)+ 继承(Inheritance)+ 通过消息的通信(Communication with Messages)
(Peter Coad 和 Edward Yourdon 提出,教材 7.1.1 节原文。)换成考试语言,就是“对象、类、继承、消息传递”四个核心概念 —— 真题 14 直接考了这句话。
这一章的知识骨架:
- 类:实体类、边界类、控制类;类与类之间有一般-特殊(继承)、整体-部分(组合/聚合)、关联等关系。
- 对象:对象名 + 属性 + 操作;对象的状态由属性值决定。
- 三大特性:封装(信息隐藏)、继承(复用父类)、多态(同一消息不同响应)。
- 两种绑定:静态绑定(编译时)、动态绑定(运行时,多态靠它)。
- 设计原则:教材列 11 条,考试集中在前 5 条(单一职责、开闭、里氏替换、依赖倒置、接口分离)加共同重用、共同封闭。
一、类:实体、边界、控制
面向对象分析里,类按职责分三种:
| 类型 | 职责 | 例子 |
|---|---|---|
| 实体类 | 保存系统中的信息,提供针对这些信息的处理 | 客户、订单、商品 |
| 边界类 | 系统内对象与系统外参与者之间的媒介 | 界面、扫码接口、二维码 |
| 控制类 | 协调实体类和边界类之间的交互 | 支付控制器、业务流程控制 |
在面向对象分析与设计中,(38)是应用领域中的核心类,一般用于保存系统中的信息以及提供针对这些信息的相关处理行为;(39)是系统内对象和系统外参与者的联系媒介;(40)主要是协调上述两种类对象之间的交互。
查看答案与解析收起答案与解析
这是“三种类”最经典的一道母题,题干三句话几乎是教材定义的原文改写。
(38)实体类,选 C。题干给的是职责描述(“应用领域中的核心类,保存系统中的信息并提供相关处理行为”),教材 7.1.1 节给的是来源描述——“实体类的对象表示现实世界中真实的实体,如人、物等”。一个说“干什么”,一个说“从哪来”,指的是同一类。控制类管流程调度、边界类管内外交互,都不负责存信息。
(39)边界类,选 B。题干说“系统内对象和系统外参与者的联系媒介”,教材的原话是“接口类(边界类)的对象为用户提供一种与系统合作交互的方式,分为人和系统两大类”。窗口、对话框、扫码接口、报表面板这些“和外界打交道的东西”都属于边界类。
(40)控制类,选 A。题干说“协调上述两种类对象之间的交互”,教材的原话是“控制类的对象用来控制活动流,充当协调者”,比如“支付控制器”“借书控制器”。
选项 D“软件类”是凑数的干扰项,面向对象分析里没有这个概念分类。
记忆口诀:实体存数据、边界管交互、控制管调度。
类( )之间存在着一般和特殊的关系。
查看答案与解析收起答案与解析
“一般和特殊的关系”就是继承关系,判断标准只有一条:能不能造出一句通顺的“子类是一种父类”(is-a)。
B:“飞机是一种交通工具”——成立。交通工具是一般(父类),飞机是特殊(子类),选 B。
A:“汽车是一种轮船”——不成立。汽车和轮船是两种并列的交通工具,属于兄弟类,共同的父类才是交通工具。
C:“轮船是一种飞机”——同样不成立,仍是兄弟关系。
D:“汽车是一种飞机”——也不成立。
A、C、D 的共同错误是把“同类”当成了“父子”:它们都是交通工具的子类,彼此之间没有继承关系。另外别把整体—部分(has-a)和一般—特殊(is-a)搞混:“汽车与发动机”是整体—部分,“汽车与交通工具”才是一般—特殊。
客户扫描二维码支付。客户类属于(39)类,二维码类属于(40)类。
查看答案与解析收起答案与解析
(39)实体类,选 B。客户是系统要长期保存、反复使用的业务对象,有属性(姓名、余额、手机号)也有操作(下单、付款),典型的实体类。
(40)接口类,也就是边界类,选 A。二维码本身不保存业务数据,它的作用是让“系统外的客户”和“系统内的支付逻辑”接上头,属于边界类。题目用“接口类”这个叫法,注意它不是 Java 里的 interface 关键字。
排掉 C、D:控制类负责协调流程(如“支付控制器”),二维码没有协调能力;状态是对象的一种特征,根本不是类的分类。
这题和真题 1 是同一套分类标准的两次考查:一次给定义让你选名字,一次给场景让你归类。
与新型冠状病毒有关的对象中,存在“一般—特殊”关系的是( )。
查看答案与解析收起答案与解析
还是那句判断:能不能说成“A 是一种 B”。
D:“确诊病人是一种发热病人”——成立。发热病人是更大的集合(一般),确诊病人是其中一部分(特殊),选 D。
A:确诊病人和治愈病人——这是同一个人在不同治疗阶段的两个状态,不是两个类,更不是父子关系。
B:确诊和疑似也是状态上的划分,一个人可以先疑似后确诊,两者并列而非包含。
C:医生和病人是两类不同的角色,谁也不是谁的一种。
这题的坑在于“病人”这个词反复出现,容易误以为都在讲同一类。判断时只看两点:是不是两个类、能不能说“是一种”。
二、对象与消息
对象的三要素:对象名、属性、操作。对象的状态由“所有属性的当前值”决定;对象之间通过消息通信。
以下关于类和对象的叙述中,错误的是( )。
查看答案与解析收起答案与解析
题目问“错误的”,选 B。
B 错在“仅可以产生一个对象”。类是一个模板、一张蓝图,用同一个类可以创建任意多个对象,每个对象有自己的属性值——Student 类可以 new 出张三、李四、王五。
A 正确。这是软考教材对类的经典表述,第 5 版 7.1.1 节的原文是“一个类定义了一组大体上相似的对象”,意思一致。注意“服务”就是“操作/方法”的另一种叫法——同一段原文里还说“一个类所包含的方法和数据描述一组对象的共同行为和属性”。
C 正确,客观世界中实际存在的是对象(类的实例),类是我们抽象出来的概念,程序运行时的“实体”是对象。
D 正确,类为属于它的全部对象提供了统一的抽象描述——正因为统一,才能复用。
这道题三个正确项把“类是什么”拆成了三句话,把这题吃透,等于背下了类的定义。
以下关于对象的叙述中,正确的是( )。
查看答案与解析收起答案与解析
选 D。对象的三要素是对象名、属性、操作。教材 7.1.1 节的原文写的是“一个对象通常可由对象名、属性和方法 3 个部分组成”——“方法”就是这里说的“操作”,同一个东西的两个叫法。
A 错在“只能包括数据”,把对象退化成了 C 语言里的结构体。
B 错在“只能包括操作”,光有方法没有数据,方法也没有可操作的对象。
C 错在“一定有相同的属性和行为”。同一类的对象共享的是属性的定义和方法的实现,但属性值可以完全不同:两个 Account 对象,一个余额 100,一个余额 0。
对象的“状态”由属性值决定,所以同类对象状态各异;“行为”由类定义,所以同类对象能做的事一样。这两句是本考点最容易被偷换的地方。
对象是运行时实体,其组成部分不包括(37);一个类定义了一组大体相似的对象,这些对象共享(38)。
查看答案与解析收起答案与解析
(37)选 A。对象的组成是对象名、属性(状态)、操作(行为)三部分;消息是两个对象之间通信的载体,它发生在对象之间,不属于某一个对象的组成部分。B、C、D 恰好就是这三要素,所以都能“组成对象”。
(38)选 D。一个类定义了一组大体相似的对象,这些对象共享属性和行为——属性名和类型相同、方法相同,但属性值可以各不相同。A 里的“状态”由属性值决定,恰恰不共享;B 的“对象名”每个对象都不同;C 的“多重度”是 UML 里描述关联数量的概念,与本题无关。
两问连起来记:类是“属性和行为”的定义,对象是“对象名 + 属性值 + 操作”的实体。
对象的( )标识了该对象的所有属性以及每个属性的当前值。
查看答案与解析收起答案与解析
选 A。状态的定义就是“对象的所有属性以及每个属性的当前值”——题干这句话本身就是定义原文。
B 唯一 ID:只回答“这个对象是谁”,不描述它现在什么样。两个对象 ID 不同,状态可以完全一样。
C 行为:回答“这个对象能做什么”,与“当前值”无关。
D 语义:太泛,面向对象里通常指一个符号所代表的含义,不是对象状态的术语。
换个角度理解:属性是“有哪些格子”,状态是“每个格子里装了什么”,行为是“能对这些格子做什么”。
三、方法重载:同名不同参
重载(overload):同一个类中,方法名相同、参数列表不同(类型、个数、顺序任一不同)。注意和**覆盖(override)**区分:覆盖是子类重新实现父类的同名同参方法。
一个类可以具有多个同名而参数类型列表不同的方法,被称为方法( )。
查看答案与解析收起答案与解析
选 A。重载(overload)的定义就是“同一个类中,方法名相同而参数列表(类型、个数、顺序)不同”。编译器靠参数列表来区分调用哪一个,所以参数列表不同是硬条件。
B 调用:是“使用一个方法”的动作,比如 obj.f(),它不会产生新的方法定义。
C 重置:面向对象里没有这个术语,纯凑数。
D 标记:Java 里的注解(@Override 之类)常被叫作标记,它给编译器看,不涉及同名方法。
补一个易混点:只有返回值类型不同不算重载,因为调用时编译器无法只凭返回值判断该选哪个。
一个类中可以拥有多个名称相同而参数表(参数类型、个数或顺序)不同的方法,称为( )。
查看答案与解析收起答案与解析
选 C。题干把条件说全了:“同一个类”“名称相同”“参数表(类型、个数或顺序)不同”,这三条正好是方法重载的定义。
A 方法标记、B 方法调用,都不是“定义多个同名方法”这件事的名字。
D 方法覆盖(override)是必错的干扰项,和重载只差一个字,含义却相反:覆盖发生在父子类之间,要求方法名、参数列表完全相同,只是实现体不同。一句话分清——重载是“同名不同参”,覆盖是“同名同参不同类”。
真题 9 和这道题问的是同一个知识点,只换了年份和措辞,说明它是高频送分点,这两个词必须分清。
四、封装:把数据和操作包起来,只露接口
封装的两层含义:① 把属性和操作结合成一个独立单元;② 尽可能隐藏内部细节,只通过接口访问。
将属性声明为 private 的目的就是信息隐藏,防止外部意外修改。
一个类是(38)。定义类时,将属性声明为 private 的目的是(39)。
查看答案与解析收起答案与解析
(38)选 D。类是“一组对象的抽象定义”,也就是模板。A“一组对象的封装”说法别扭,封装是动作,不是类的定义;B 讲的是层次关系(继承),不是类本身;C“一组对象的实例”把类和对象说反了——实例是对象,不是类。
(39)选 A。把属性声明为 private,目的就是信息隐藏,让外部不能直接读写,只能通过类提供的 public 方法访问,从而避免意外修改。
B 操作符重载与访问控制无关。C 是精心设计的陷阱:“不可更改”和“不可直接访问”不是一回事——private 属性照样能被类内方法修改,只是外部改不了。D 描述的是 static 成员(类变量)的特性,与 private 无关。
封装是一种( )技术,其目的是使对象的使用者和生产者分离。
查看答案与解析收起答案与解析
选 B。封装的本质是信息隐藏:把内部实现藏起来,只暴露接口。教材的表述是封装“使对象的使用者和生产者分离”——使用者按接口调用,生产者改内部实现不影响使用者,这就是“分离”。
A 接口管理只是封装带来的结果之一,不是封装的技术本质。
C 多态是“同一消息不同响应”,讲的是调用时的动态行为,与隐藏无关。
D 聚合是“整体—部分”的关联关系,属于类间关系,不是封装。
以下关于封装在软件复用中所充当的角色的叙述,正确的是( )。
查看答案与解析收起答案与解析
题目问封装在软件复用中的作用,选 A。
A 说对了复用的关键:复用者只需知道组件“能做什么”(接口),不必知道“怎么做”(内部实现),别人写的组件才能直接拿来用。
B 错,封装不改变组件的执行逻辑,不会让它跑得更快,多一层方法调用反而可能有微小开销。
C 错得离谱,封装替代不了文档,接口说明、使用约束仍然要写。
D 要小心:封装让“复用”变容易,但组件开发本身并没有变简单——设计接口、划分职责反而更费心思。题目问的是复用,所以不能选 D。
对象、类、继承和消息传递是面向对象的 4 个核心概念。其中对象是封装( )的整体。
查看答案与解析收起答案与解析
选 D。对象是封装数据和行为的整体:数据是属性,行为是操作(方法),两者绑在同一个单元里,这是对象区别于“单纯的数据结构”的根本。
A 命名空间是 C++/C# 里避免名字冲突的机制,不是对象封装的内容。
B“要完成的任务”太笼统,一个对象可能承担多项任务,任务本身不是被封装的东西。
C“一组数据”只说了一半,正是典型的半对型错误:只有数据没有行为,那是结构体,不是对象。
题干这句话有出处:教材 7.1.1 节引 Peter Coad 和 Edward Yourdon 的等式——面向对象 = 对象 + 分类 + 继承 + 通过消息的通信,翻译成考试语言就是“对象、类、继承、消息传递”四个核心概念。本题只考了第一个,但“封装数据和行为”这句话在后面的封装、信息隐藏题里会反复出现。
将逻辑上相关的数据和行为绑定在一起,使信息对使用者隐蔽称为(37)。当属性或方法被设计为 private 时,(38)可以访问。
查看答案与解析收起答案与解析
(37)选 C。“逻辑上相关的数据和行为绑定在一起”+“信息对使用者隐蔽”,两个特征同时命中封装。抽象是“提取共同特征、忽略无关细节”;继承是父子类共享;多态是同一消息不同响应,都对不上。
(38)选 B。private 的可见范围是本类内部,只有这个类里定义的方法能访问。
A“应用程序中所有方法”相当于 public。C“只有此类中定义的 public 方法”是陷阱:private 属性的访问权限看的是“方法在哪个类里”,而不是“方法本身是不是 public”。D 是 Java 的包访问权限(默认/package-private),private 比它还严,同包的其他类也访问不了。
Java 四档访问权限从小到大:private → 默认 → protected → public,这题考的是最小的一档。
一个类中,成员变量和成员函数有时也可以分别被称为( )。
查看答案与解析收起答案与解析
选 D。成员变量在面向对象语境里叫属性,成员函数叫方法(也叫操作、服务),这是最标准的两个叫法。
A、C 里的“活动”是 UML 中的另一个概念(活动图里的 action/activity),描述流程步骤,不是成员函数。
B“值和方法”不对,成员变量不只是“值”,它是带名字和类型的属性定义。
这是纯术语题,几乎每年换个说法考一次。记住同义词链条:属性=成员变量=数据;方法=成员函数=操作=服务。
C++、Java 中,关键字( )可以用于区分同名的对象属性和局部变量名。
查看答案与解析收起答案与解析
选 D。this 是当前对象的引用,写 this.name = name 时,左边的 this.name 指对象的属性,右边的 name 指方法参数,同名也不会打架。C++ 里用 this->,Java 里用 this.,作用一样。
A、B、C 三个都是访问修饰符(private、protected、public),它们管的是“这个成员谁能访问”,完全不参与“同名变量如何区分”。
顺带记住它们的范围(真题 15 考过):private 只本类,默认同包,protected 同包加子类,public 全部。
还要注意 this 不能用在 static 方法里——静态方法属于类,没有“当前对象”。
五、继承:父类的属性和方法自动拥有
继承定义“一般—特殊”关系;子类自动拥有父类的全部属性和方法,并可以新增自己的属性和方法。Java 不支持类的多继承(一个子类只能有一个父类),C++ 支持多继承,多继承可能带来二义性。
(38)是把对象的属性和服务结合成一个独立的系统单元,并尽可能隐藏内部细节;(39)是指子类可以自动拥有父类的全部属性和服务;(40)是对象发出的服务请求,包含对象标识、服务标识、输入信息和应答信息。
查看答案与解析收起答案与解析
三个定义分别对应本章三个“母概念”:
(38)选 D。封装:把属性和服务结合成独立单元,并尽可能隐藏内部细节,题干两个分句都说全了。
(39)选 A。继承:子类自动拥有父类的全部属性和服务。“自动拥有”是关键词,不用重新写一遍。
(40)选 C。消息:对象发出的服务请求,由对象标识、服务标识、输入信息、应答信息四部分组成。
B 多态在这里是干扰项:多态说的是“同一消息被不同对象接收后产生不同响应”,题干没提“不同响应”,所以不能选。
这三句话是后面大量题的题干来源,建议原样背下来。
以下关于面向对象继承的叙述中,错误的是( )。
查看答案与解析收起答案与解析
问“错误的”,选 D。
D 错在把“仅仅允许单重继承”当成继承的普遍规则。事实上 C++ 支持一个子类有多个父类(多继承),Java 只允许类的单继承但允许实现多个接口。多继承还会带来二义性——两个父类有同名成员时调用会歧义,C++ 用虚基类解决。
A 正确,是教材原话:“继承是父类和子类之间共享数据和方法的机制”。
B 正确,继承就是一种类与类之间的关系,UML 里画成空心三角箭头,叫泛化。
C 正确,子类拥有父类的全部属性和方法——是全部,包括 private 成员,只是 private 成员子类不能直接访问,但它确实被继承了。
陷阱在于 C 和 D 都涉及“能不能有多个父类”,但 C 说的是“拥有父类的东西”,D 说的是“父类的数量”,别被绕进去。
面向对象技术中,(41)定义了超类和子类之间的关系;子类以更具体的方式实现从父类继承来的方法称为(42);不同类的对象通过(43)相互通信。
查看答案与解析收起答案与解析
(41)选 B。继承定义的就是超类(父类)和子类之间的关系,UML 里叫泛化(generalization)。
(42)选 A。覆盖(override):子类用更适合自己的实现,替换父类中同名同参方法的实现。“以更具体的方式实现”是关键提示。
(43)选 C。消息是不同类的对象之间相互通信的方式,一个对象发消息,另一个对象响应。
D 多态是这三者共同作用的结果:继承建立关系、覆盖提供不同实现、消息触发调用,运行时才表现出多态。题目问的是“通信”,只能选消息。
串成一条线记:继承建立关系 → 覆盖改变实现 → 消息完成通信 → 多态显现效果。
在面向对象方法中,(37)是父类和子类之间共享数据和方法的机制。子类在原有父类接口的基础上,用适合于自己要求的实现去置换父类中的相应实现称为(38)。
查看答案与解析收起答案与解析
(37)选 B。题干“父类和子类之间共享数据和方法的机制”,这是教材给继承下的定义,一字不差。
(38)选 C。“用适合于自己要求的实现去置换父类中的相应实现”就是覆盖(override)。注意“置换”两个字——接口不变、实现换掉,正是覆盖的特征。
A 封装是绑定与隐藏,D 多态是同一消息不同响应,都不是“替换父类实现”这个动作。
两问其实是一套完整逻辑:继承把父类的方法拿到手,覆盖把它改成自己需要的样子,多态让调用方不必关心到底是哪个子类。
两个及以上的类作为一个类的超类时,称为(37),使用它可能造成子类中存在(38)的成员。
查看答案与解析收起答案与解析
(37)选 A。“两个及以上的类作为一个类的超类”就是多重继承,即一个子类有多个直接父类。
B 多态是同一消息不同响应,跟父类数量无关。C 封装是绑定与隐藏。D 层次继承指单继承形成的树形层次(一个父类、多个子类),题干说的是“多个父类”,方向正好相反。
(38)选 D。多继承最典型的副作用就是二义性:两个父类都有同名成员(比如都有 print())时,子类对象调用 print() 编译器不知道走哪一条。
C++ 的解决办法是加作用域限定,写成 父类名::成员,或者用虚基类;Java 干脆不支持类的多继承,只允许实现多个接口,从语言层面回避了这个问题。
A 动态、B 私有、C 公共都属访问控制范畴,与多继承的副作用无关。
采用继承机制创建子类时,子类中( )。
查看答案与解析收起答案与解析
选 D。子类在继承父类全部属性和行为的基础上,还可以新增自己的属性和行为——继承的价值正是“复用 + 扩展”。
A“只能有父类中的属性”、B“只能有父类中的行为”:都把子类说成了父类的复制品,那样继承就毫无意义。
C“只能新增行为”:漏了属性。子类完全可以加自己的成员变量,比如 Employee 继承 Person 后新增 salary、dept。
UML 里把子类特有的部分叫“扩展”,父类已有的部分叫“继承”。设计中还有一个约束:子类可以新增、可以覆盖,但不应该删除父类的行为,否则就违反里氏替换。
在面向对象方法中,继承用于( )。
查看答案与解析收起答案与解析
选 A。继承的用途是在已存在的类的基础上创建新类:老类是父类,新类是子类,新类自动获得老类的能力再加以扩展。
B“在已存在的类中添加新的方法”、C“添加新的属性”:这是在修改同一个类,不是创建新类。真这么干,改的是父类本身,所有使用者都受影响,恰恰是开闭原则反对的做法。
D“在已存在的状态中添加新的状态”:状态是对象运行时属性值的组合,谈不上“添加”,与继承无关。
辨别点只有一个:继承一定要产生新类。凡是描述“在原有类上加东西”的选项,都不选。
六、多态:同一消息,不同响应
多态(polymorphism):不同对象收到同一消息可以产生完全不同的结果。它依赖两个前提:继承(有共同的父类)+ 覆盖(子类各自实现)。
教材按 Cardelli 和 Wegner 的划分,把多态分 4 类,而且两两一组:
| 形式 | 标志 | 例子 | 归属 |
|---|---|---|---|
| 参数多态 | 类型参数化 | C++ 模板、Java 泛型 | 通用 |
| 包含多态 | 子类型化 | 父类引用指向子类对象 | 通用 |
| 过载多态 | 同名不同参 | 重载方法 | 特定 |
| 强制多态 | 类型转换 | int 隐式转 double | 特定 |
教材原话:参数多态和包含多态称为通用的多态,过载多态和强制多态称为特定的多态。另外两句容易考的定性是——参数多态“被称为最纯的多态”,包含多态“最常见的例子就是子类型化”。
这两组不是纯记忆:通用多态靠类型系统在编译期支撑,特定多态靠名字解析或类型转换实现。考题里如果问“哪种是特定的多态”“哪种被称为最纯的多态”,答案都在上面这张表里。
在面向对象技术中,(38)说明一个对象具有多种形态,(39)定义超类与子类的关系。
查看答案与解析收起答案与解析
(38)选 D。多态的通俗解释就是“一个对象具有多种形态”:同一族对象在不同上下文里表现出不同的行为。
(39)选 A。继承定义超类与子类的关系,也就是泛化关系。
B 组合是整体与部分的关系(has-a),比如“汽车与发动机”,两个类之间没有父子之分。C 封装是把数据和行为打包并隐藏细节,不涉及类间关系。
两问其实是配套的:继承提供了“同一族类”这个前提,多态才有发挥空间——没有共同父类,就无法用同一条消息统一处理。
在多态的几种不同形式中,( )多态是一种特定的多态,指同一个名字在不同上下文中可代表不同的含义。
查看答案与解析收起答案与解析
选 C。题干关键词是“同一个名字在不同上下文中可代表不同的含义”,这正是过载(重载)多态:同名方法因参数列表不同而承担不同语义。
A 参数多态:用类型参数让同一份代码适配多种类型,典型是 C++ 模板、Java 泛型,与“名字相同、含义不同”不是一回事。
B 包含多态:子类型替换,父类引用指向子类对象,最常见的是继承体系里的方法覆盖。
D 强制多态:类型转换带来的多态,比如 int 隐式转成 double 参与运算。
四种多态是固定考点,各配一个例子记:过载看“同名不同参”,包含看“子类型”,参数看“泛型”,强制看“类型转换”。
不同对象收到同一消息可产生完全不同的结果,这一现象称为(39),它由(40)机制支持。
查看答案与解析收起答案与解析
(39)选 D。“不同对象收到同一消息可产生完全不同的结果”,这是多态的定义原句。
(40)选 B。多态由继承机制支持:正因为这些对象有共同的父类(或共同接口),才能用同一条消息统一发给它们,再由各自实现产生不同响应。
要提醒的是,严格来讲多态需要“继承 + 覆盖 + 动态绑定”三者配合,但本题四个选项里只有“继承”属于支持多态的机制,动态绑定并未出现在选项中,所以官方答案是 B。
A 绑定是实现手段之一,C 消息是通信方式,都不如“继承”贴合“机制支持”这个问法。这类题先看选项有什么,再选最贴切的那个,不要死抠教材的完整表述。
多态分为参数多态、包含多态、过载多态和强制多态,其中( )多态在许多语言中都存在,最常见的例子就是子类型化。
查看答案与解析收起答案与解析
选 B。包含多态的标志就是子类型化:父类类型的变量可以引用子类对象,从而“包含”了所有子类型。
Java 里写 Animal a = new Cat(); 就是包含多态——变量声明的是父类型,实际装的是子类实例,调用 a.move() 时执行的是 Cat 的实现。
A 参数多态对应泛型,如 List<T>,同一份代码适配不同类型。C 过载多态是同名不同参。D 强制多态是类型转换。
题干“在许多语言中都存在,最常见的例子就是子类型化”几乎把答案写在脸上,考场上看到“子类型”三个字直接选包含。
不同对象收到同一消息可以产生完全不同的结果,这一现象称为( )。使用时,用户可以发送一个通用的消息,而实现的细节由接收对象自行决定。
查看答案与解析收起答案与解析
选 D。题干两句话合起来就是多态的完整定义:前半句“不同对象收到同一消息产生完全不同结果”,后半句“用户发送通用消息,实现细节由接收对象自行决定”。
A 接口:接口只定义一组方法签名,它是多态得以实现的载体,但“通用消息、各自决定”这个现象本身叫多态。
B 继承:继承提供共同父类这个前提,也是前提而非现象。
C 覆盖:覆盖是子类改写父类方法这个动作,是多态链条中的一环。
四个词是一条链上的四个环节:继承(前提)→ 覆盖(手段)→ 动态绑定(机制)→ 多态(现象)。题目问“现象”,只能选多态。
在面向对象方法中,多态指的是( )。
查看答案与解析收起答案与解析
选 A。多态对使用者最大的价值就是:面向父类或接口编程,不必知道具体是哪个子类的实现。调用方只写 animal.move(),到底是鸟飞还是猫跑,由运行时对象的真实类型决定。
B“对象动态地修改类”完全错误。对象的类在创建时就确定了,运行期不能改变它的类型定义;能改的是属性值,不是类。
C“一个对象对应多张数据库表”是对象—关系映射(ORM)里的话题,与多态无关。
D“子类只能够覆盖父类中非抽象的方法”错在两处:抽象方法必须被子类实现(这正是多态的典型场景),非抽象方法也可以被覆盖。而且这句话描述的是覆盖的规则,不是多态的定义。
同一消息可以调用多种不同种类的对象的方法,这些类有某个相同的超类,这种现象是( )。
查看答案与解析收起答案与解析
选 D。题干给了三个关键词:“同一消息”“多种不同种类的对象”“有某个相同的超类”,三个条件凑齐就是多态。
A 类型转换:把一个类型转成另一个类型,比如向上转型、强制转换,它可能被用来实现多态,但现象本身不叫类型转换。
B 映射:一般指对象与关系数据库表之间的对应(ORM),或集合中键到值的对应,与本题无关。
C 单态:不是面向对象的标准术语,纯干扰项。
这题和真题 29、30 是同一年不同场次的重复考点,说明“同一消息 + 共同超类 + 不同响应”这三件套必须背熟。
( )多态是指操作(方法)具有相同的名称、且在不同的上下文中所代表的含义不同。
查看答案与解析收起答案与解析
选 C。“操作(方法)具有相同的名称、且在不同的上下文中所代表的含义不同”,这就是过载多态的定义,和真题 26 完全同义,只换了年份。
A 参数多态是泛型:一份代码适配多种类型。B 包含多态是子类型替换。D 强制多态是类型转换。
四种多态几乎年年考,题干措辞高度固定,认准标志词即可:出现“同名不同上下文”就是过载,出现“子类型”就是包含,出现“泛型/模板”就是参数,出现“类型转换”就是强制。
多态有不同的形式,( )的多态是指同一个名字在不同上下文中所代表的含义不同。
查看答案与解析收起答案与解析
选 C。“同一个名字在不同上下文中所代表的含义不同”——过载多态。这已经是 2013 上、2018 下、2020 下第三次用同一句话出题。
A 参数、B 包含、D 强制三种多态的定义都不含“同名”这个特征:参数多态讲类型参数化,包含多态讲子类型可替换,强制多态讲隐式类型转换。
三次重复说明它是必拿分。考场上看到“同一个名字/同一名称 + 不同上下文/不同含义”,直接选过载,不用犹豫。
Bird 和 Cat 是 Animal 的子类,Parrot 是 Bird 的子类。bird、cat、parrot 分别是三个类的对象。以下叙述不正确的是(39);Animal 定义 move(),三个子类各自实现,调用时不同对象产生不同结果,这一现象称为(40)。
查看答案与解析收起答案与解析
(39)问“不正确的”,选 C。这是本章唯一一道要推关系的题,把继承链画出来就清楚了:
Animal ← Bird ← Parrot,同时 Animal ← Cat。箭头从子类指向父类。
规则只有一条:子类对象可以当作父类对象使用(向上转型,永远安全);父类对象不能当作子类对象使用(向下转型,必须强制且运行时可能出错)。
A:cat 是 Cat 的对象,Cat 是 Animal 的子类,可以看作 Animal 的对象——正确。
B:parrot 是 Parrot 的对象,Parrot → Bird → Animal 一路向上,可以看作 Animal 的对象——正确。
D:parrot 可以看作 Bird 的对象——Parrot 直接继承 Bird,正确。
C:bird 是 Bird 的对象,而 Parrot 是 Bird 的子类。把父类对象当成子类对象,等于说“所有鸟都是鹦鹉”,明显错误,所以选 C。
(40)选 D。Animal 定义 move(),三个子类各自实现,同一条 move() 消息发给不同对象得到不同结果,这就是多态。封装是绑数据和行为,继承是共享父类,消息传递只是通信方式,都不描述“不同结果”这个现象。
七、静态绑定与动态绑定
- 静态绑定:编译时就把“调用”和“代码”结合好(如普通函数调用、重载)。
- 动态绑定:运行时才根据对象的实际类型决定调用哪段代码(如虚函数、父类引用调用子类覆盖的方法)——多态靠它实现。
不同对象收到同一消息产生不同结果,这一现象叫(38)。绑定是把过程调用和响应调用所需执行的代码加以结合。编译时进行的绑定叫(39);运行时进行的绑定叫(40)。
查看答案与解析收起答案与解析
(38)选 B。同一消息、不同结果 = 多态。
(39)选 D。题干已经给了绑定的定义:“把过程调用和响应调用所需执行的代码加以结合”。在编译时完成结合的是静态绑定(早期绑定),编译器看变量声明的类型就定死了调用哪一个。
(40)选 C。在运行时才结合、根据对象真实类型决定走哪份代码的是动态绑定(晚期绑定)。
两问的区别只有四个字:编译时 / 运行时。静态绑定快但不够灵活,动态绑定灵活但有运行期开销,多态必须依赖动态绑定。
A 继承提供“同一族类”这个前提,但题干问的是绑定的两种时机,与继承无关。
过程调用和响应调用需执行的代码的绑定直到运行时才进行,这种绑定称为( )。
查看答案与解析收起答案与解析
选 B。“直到运行时才进行”是唯一判据——运行时绑定就是动态绑定。
A 静态绑定恰好相反,在编译(或链接)阶段就确定了调用地址,比如 C 里的普通函数调用、Java 里的 private/static/final 方法。
C“过载绑定”、D“强制绑定”都不是标准术语,属于凭空造词。重载虽然在编译期就能确定调用哪一个(靠参数列表),但那叫静态绑定,不叫“过载绑定”。
这题和真题 35、37、39、40 是同一考点,几年内考了至少五次。看到“运行时”三个字,答案就是动态绑定。
运行过程中,当一个对象发送消息请求服务时,根据接收对象的具体情况将请求的操作与实现的方法进行连接,称为( )。
查看答案与解析收起答案与解析
选 C。题干关键词是“运行过程中”“根据接收对象的具体情况”——消息发给谁就调用谁的实现,这个决定发生在运行时,所以是动态绑定。
A 静态绑定在编译时就定死了,不会“根据接收对象的具体情况”变化。
B“通用绑定”、D“过载绑定”都不是标准术语。注意“通用”容易让人联想到题干里的“通用消息”,但那是多态的效果,不是绑定的类型。
换个说法记:静态绑定看“变量声明的类型”,动态绑定看“对象实际的类型”。
在面向对象方法中,支持多态的是( )。
查看答案与解析收起答案与解析
选 D。题目问“支持多态的是”什么——多态的实现机制就是动态绑定:调用时才根据对象的真实类型,把消息和方法实现连起来。
A 静态分配、C 静态类型都是编译期概念,恰恰与多态所需的“运行期决定”相反。
B 动态分配是内存管理术语(堆上分配、运行时确定大小),虽然也带“动态”二字,但和多态没关系,这是本题唯一像样的干扰项。
注意和真题 27(2014 上 40)的区别:那道题选项里有“继承”,所以选继承;这道题选项里有“动态绑定”,所以选动态绑定。同一知识点,选项不同答案不同,考场要按选项说话。
运行时把过程调用和代码结合叫(38);编译时结合叫(39)。
查看答案与解析收起答案与解析
(38)选 D。运行时把过程调用和代码结合 = 动态绑定。
(39)选 C。编译时结合 = 静态绑定。
A 消息传递是对象之间的通信方式,B 类型检查是编译器验证类型是否兼容的过程,两者都不是“把调用和代码结合”。
这题把真题 35 的两个空对调了顺序,正是出题人常用的手法——同一个知识点,问法顺序一变,死记“第一空静态、第二空动态”的人就翻车。记概念,别记位置。
( )绑定是指在运行时把过程调用和响应调用所需要执行的代码加以结合。
查看答案与解析收起答案与解析
选 A。“运行时把过程调用和响应调用所需要执行的代码加以结合”——动态绑定,本章第四次考同一句话。
C 静态绑定是编译时结合,与题干相反。B 过载、D 参数都不是绑定的类型:过载是“同名不同参”,参数多态是泛型,两者都不描述“何时把调用和代码结合”。
这道题的四个选项把“绑定”和“多态”两类概念混在一起做干扰,只要抓住“运行时”三个字,一眼就能定答案。
八、面向对象设计原则
教材第 5 版 7.1.3 节一共列了 11 条设计原则。不过命题只在前 5 条和两条“共同”原则上出过题,其余 4 条是讲包的划分的,教材有、真题没考过。先把考试范围内的 7 条按“一句话 + 一个关键词”记住:
| 原则 | 一句话 | 关键词 |
|---|---|---|
| 单一职责 SRP | 一个类只有一个引起它变化的原因 | 职责单一 |
| 开闭 OCP | 对扩展开放,对修改关闭 | 扩展 |
| 里氏替换 LSP | 子类对象能替换任何基类对象出现的地方 | 基类/子类 |
| 依赖倒置 DIP | 依赖抽象,不依赖实现(教材译“倒置”,也写作“倒转”) | 抽象 |
| 接口分离 ISP | 不强迫客户依赖他们不用的方法 | 接口属于客户 |
| 共同重用 CRP | 重用包中一个类就要重用包中所有类 | 一起重用 |
| 共同封闭 CCP | 一个变化影响一个包,就影响包中所有类 | 一起变化 |
教材里另外 4 条是 Robert C. Martin 针对包的划分提出的,配合上面的表一起看,就知道为什么有的题会冒出没见过的名字:
- 重用发布等价原则 REP:重用的粒度就是发布的粒度。一个包要么整体发布、要么不发布,不能只把包里的一个类单独拿出去发版。
- 无环依赖原则 ADP:包的依赖关系图中不允许存在环。A 依赖 B、B 又依赖 A,改一处就会连锁反应,测试和发布都无法独立。
- 稳定依赖原则 SDP:依赖要朝着“稳定”的方向。不稳定的包应该依赖稳定的包,反过来会让稳定的包被频繁变动拖累。
- 稳定抽象原则 SAP:包的抽象程度应该和它的稳定程度一致。越稳定的包越应该抽象(放接口、放父类),这样扩展时不用改它。
以下关于面向对象设计的叙述中,错误的是( )。
查看答案与解析收起答案与解析
问“错误的”,选 D。
依赖倒转原则(DIP)的原话有两条:① 高层模块不应该依赖于底层模块,二者都应该依赖于抽象;② 抽象不应该依赖于细节,细节应该依赖于抽象。
A 正确,对应第①条前半句。B 正确,对应第②条前半句。C 正确,对应第②条后半句——细节依赖抽象,正是“倒转”二字的由来。
D 错在“无法不依赖”。它把现状(很多代码确实直接依赖底层实现)当成了原则,恰恰违背 DIP 的初衷。依赖倒转要做的就是用接口把这种直接依赖切断。
最常见的例子:业务层不要直接 new 一个 MySQL 的 Dao,而要依赖 Repository 接口,MySQL 实现和 Oracle 实现都去实现这个接口。这样换数据库时业务层一行不用改。
开闭原则:对(37)开放、对(38)关闭;里氏代换:任何(39)可以出现的地方,(40)一定可以出现;依赖倒转:依赖(41),不依赖(42)。
查看答案与解析收起答案与解析
六个空对应三条设计原则,逐条看:
(37)(38)开闭原则:对扩展开放、对修改关闭,选 B、A。意思是新功能靠“加新代码”实现,而不是“改老代码”。
(39)(40)里氏代换原则:任何基类对象可以出现的地方,子类对象一定可以出现,选 C、D。方向不能反,反过来不成立。
(41)(42)依赖倒转原则:依赖抽象,不依赖实现,选 D、C。
A 修改、B 扩展这两个词在开闭原则里成对出现,别记反:开放的是扩展,关闭的是修改。
这六空把三条最常考的原则一次考完,是设计原则部分的骨架题。剩下四条——单一职责、接口分离、共同重用、共同封闭——通常单独出单选题。
就一个类而言,应该仅有一个引起它变化的原因,这属于( )设计原则。
查看答案与解析收起答案与解析
选 A。“就一个类而言,应该仅有一个引起它变化的原因”,这是单一职责原则(SRP)的定义原句。一个类只承担一项职责,将来需求变了,改它的理由也就只有一个,不会牵一发而动全身。
B 开放—封闭讲的是“对扩展开放、对修改关闭”,关键词是扩展与修改,不是“变化的原因”。
C 接口分离讲的是“不强迫客户依赖不用的方法”,关注接口粒度,不是类的职责数量。
D 里氏替换讲的是“基类对象出现的地方,子类都能替换”,关注父子类的可替换性。
反例帮助理解:一个类同时负责“计算工资”和“打印工资单”,计算规则变了要改它,打印格式变了还要改它——两个变化原因,就违反了 SRP。
软件实体应该是可以扩展但不可修改的,这属于( )设计原则。
查看答案与解析收起答案与解析
选 B。“软件实体应该是可以扩展但不可修改的”就是开放—封闭原则(OCP)的标准表述:对扩展开放、对修改关闭。
A 共同重用的是“重用一个包的类就要重用整包”,讲包的复用粒度。C 接口分离讲接口不该强迫客户依赖不用的方法。D 共同封闭讲“一个变化只影响一个包内的类”。三个都与“扩展/修改”无关。
OCP 实现的关键是抽象:把可能变化的部分抽象成接口或父类,新需求来了就加一个实现类,老代码不动。所以它常和依赖倒转、里氏替换配合使用。
一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对其他包不造成影响,这属于( )原则。
查看答案与解析收起答案与解析
选 D。共同封闭原则(CCP)说的是:一个变化如果对一个包产生影响,就对该包中所有类产生影响,而对其他包不造成影响。也就是把“会一起变化的类”放进同一个包,让变化被“封闭”在包内。
A 共同重用(CRP)方向相反:它讲的是“重用一个类就要重用整包”,关注复用的完整性。B 开放—封闭是类级别的扩展与修改。C 接口分离讲接口粒度。
这两个“共同”原则最容易混,一句话区分:共同封闭管“变化一起变”,共同重水管“复用一起用”。前者按“会不会同时改”分包,后者按“会不会同时用”分包。
不应该强迫客户依赖于他们不用的方法,接口属于客户……这属于( )。
查看答案与解析收起答案与解析
选 C。“不应该强迫客户依赖于他们不用的方法”“接口属于客户”,这是接口分离原则(ISP)的两句原话。
它的意思是:接口要按使用者的需要来切分,而不是把一堆方法塞进一个大接口。客户只关心自己用到的那几个方法,用不上的方法不该让它看见、更不该逼它实现。
A 单一职责管的是一个类只有一个变化原因,讲“类的职责”,不是“接口的粒度”。B 开放—封闭讲扩展与修改。D 里氏替换讲父子类替换。
典型反例:一个 IWorker 接口里塞了 work()、eat()、sleep(),机器人只需要 work(),却被迫实现另外两个空方法——这就是没做接口分离。
如果重用了包中的一个类,那么就要重用包中的所有类,这属于( )原则。
查看答案与解析收起答案与解析
选 D。“如果重用了包中的一个类,那么就要重用包中的所有类”,这是共同重用原则(CRP)的原话。
它是一条包的设计准则:一个包里的类应该是“要么一起用、要么一起不用”的关系,不要出现“我只想用你包里的 A,却被迫拖进 B、C、D”的情况。
A 接口分离管接口粒度。B 开放—封闭管扩展与修改。C 共同封闭管“一个变化只影响本包”。
和真题 45 对照记:共同封闭是“变化一起变”(按变化分包),共同重用的是“复用一起用”(按使用分包)。题干出现“重用”二字就是共同重用,出现“变化影响”就是共同封闭。
九、面向对象分析与设计
- OOA(面向对象分析):理解问题,回答“做什么”,不关注实现细节。活动顺序:认定对象 → 组织对象 → 描述对象间相互作用 → 确定对象的操作。
- OOD(面向对象设计):理解解决方案,回答“怎么做”,依赖 OOA 的结果,会关注技术和实现细节。
下面关于 OOA 与 OOD 的说法中,不正确的是( )。
查看答案与解析收起答案与解析
问“不正确的”,选 D。
D 说“OOD 一般不关注技术和实现层面的细节”,恰好说反了。OOA 才是忽略实现、专注问题域的;OOD 恰恰要落到技术方案上——分几层、用什么数据库、接口怎么定、并发怎么处理,都是设计阶段要定的事。
A 正确,OOA 侧重“理解问题”,搞清楚系统要解决什么。
B 正确,OOD 侧重“理解解决方案”,即用什么结构去实现。
C 正确,OOA 描述“软件要做什么”(what),OOD 描述“怎么做”(how)。
一句话串起来:OOA 面向问题域,OOD 面向解空间。判题时只要看到“设计不关注实现”,就可以判错。
以下关于面向对象分析的叙述中,错误的是( )。
查看答案与解析收起答案与解析
问“错误的”,选 B。
B 说“OOA 需要考虑系统的测试问题”,不对。测试是分析、设计之后的独立阶段,OOA 的职责是把问题域搞清楚,不承担可测试性设计,更不制定测试方案。
A 正确,OOA 着重分析问题域和系统责任——问题域是“业务是什么”,系统责任是“系统该担什么”。
C 正确,OOA 忽略与系统实现有关的问题,比如用什么语言、用什么数据库。
D 正确,OOA 建立的模型独立于实现,所以同一份分析模型可以用 Java 实现,也可以用 C# 实现。
C 和 D 其实是一体两面:正因为忽略实现,模型才独立于实现。
( )不是面向对象分析阶段需要完成的。
查看答案与解析收起答案与解析
选 C。“实现对象及其相互关系”是设计、编码阶段的事,分析阶段不实现任何东西。
OOA 的活动是四步:认定对象、组织对象、描述对象间的相互作用、确定对象的操作。A、B、D 正好是前三项,都属于分析阶段。
补一句教材口径:第 5 版 7.1.2 节其实列了 5 个活动,最后还多一个“定义对象的内部信息”(对象内部的数据、存储方法、继承关系、可能的实例数)。它排在“确定操作”之后,仍在分析阶段内,只是历年真题的四个选项都没把它列进来,所以按四步判断即可。
“实现”这个词在软考里是明确的信号:只要出现“实现”“编码”“编程”,就不属于分析阶段。分析只回答“有什么、什么关系、做什么”,不回答“怎么写”。
另外注意,D“描述对象间的相互作用”与 A、B 合起来就是上面那四项,真题 55 会完整考一次顺序。
以下关于面向对象设计的叙述中,错误的是( )。
查看答案与解析收起答案与解析
问“错误的”,选 A。
A 把顺序说反了:面向对象开发是先分析(OOA)、后设计(OOD),分析的结果是设计的输入。它给的理由“只有产生了设计结果才可对其进行分析”更是本末倒置——没有分析,设计根本无从下手。
B 正确,OOA 和 OOD 是面向对象软件过程中两个重要阶段,通常再加上 OOP(程序设计)和 OOT(测试)。
C 正确,OOD 依赖 OOA 的结果,不能凭空设计。
D 正确,两者形式上可以类似,都可以用 UML 表达——OOA 用类图、用例图描述问题域,OOD 用类图、序列图、部署图描述解方案。
面向对象分析的第一步是( )。
查看答案与解析收起答案与解析
选 C。面向对象分析的第一步是确定问题域:先搞清楚系统要解决的业务范围是什么、边界在哪里,然后才谈得上从里面找对象。
D“定义类和对象”看起来很像第一步,其实更靠后——你得先知道问题域,才知道该去哪些名词里找候选对象。
A“定义服务”、B“确定附加的系统约束”都更靠后:先有对象,才谈得上对象的操作;约束通常在模型基本成型后补充。
这题和第 55 题的四步法看似冲突(那边第一步是“认定对象”),其实是两个层次:确定问题域是“划定范围”,认定对象是“在范围内找东西”。考场上按选项选最贴切的那个。
面向对象分析的目的是获得对应用问题的理解,其主要活动不包括( )。
查看答案与解析收起答案与解析
选 C。“面向对象程序设计”属于实现阶段(OOP),不是分析活动。
OOA 的主要活动是四项:认定并组织对象(A)、描述对象间的相互作用(B)、确定基于对象的操作(D)。这三项在选项里都出现了,只有 C 是混进来的。
题干问的是“主要活动不包括”,这类题的做法是把四个选项逐个往“分析/设计/实现”三阶段里归位:A、B、D 都在分析,C 在实现,答案自然浮出来。
顺带记:OOA 的产出是分析模型(类图、用例图、交互图),OOD 的产出是设计模型(含包图、部署图),OOP 的产出才是代码。
面向对象分析过程中,从给定需求描述中选择( )来识别对象。
查看答案与解析收起答案与解析
选 B。从需求描述中识别对象,最常用的启发式规则是找名词短语:需求里反复出现的名词,往往就是候选的类或对象。
A 动词短语对应的是操作/方法,比如“计算总价”“提交订单”,它们是对象的行为,不是对象本身。
C 形容词往往对应属性值或约束,比如“红色的”“加急的”,通常落成某个属性的取值,而不是一个类。
D 副词修饰动作,连属性都算不上。
举个例子:“客户提交订单,系统计算总价”——名词有客户、订单、总价,动词有提交、计算。“客户”“订单”是对象,“提交”“计算”是操作。这就是名词/动词分析法。
面向对象分析时,执行的活动顺序通常是( )。
查看答案与解析收起答案与解析
选 A。面向对象分析的标准四步:认定对象 → 组织对象 → 描述对象的相互作用 → 确定对象的操作。
这里要说清一个容易踩坑的地方:教材第 5 版 7.1.2 节列的是 5 个活动——在上述四步之后还有一步“定义对象的内部信息”(内部数据、存储方法、继承关系、可能的实例数)。而本题四个选项都只排到“确定操作”为止,所以按四步选 A。换句话说:教材五步、试卷四步,选项里没有第五步就选四步的那个。
B 错在多插了一步“定义属性”,而且位置不对:属性通常随类一起细化,不属于分析的四步主流程;更关键的是它漏了“描述相互作用”。
C 顺序乱了:先描述相互作用、后确定操作,而且末尾多出“识别包”——识别包是设计阶段的活动。
D 是典型的把设计活动混进来:“识别类及对象、识别关系、定义属性、确定操作”更像 OOD 的内容,顺序也不对。
记这四步有个顺口的方法:先找“谁”(认定对象),再分“组”(组织对象),然后看“怎么打交道”(相互作用),最后定“能干什么”(操作)。
面向对象设计时包含的主要活动是( )。
查看答案与解析收起答案与解析
选 D。面向对象设计要落到实现层面的五件事:识别类及对象、定义属性、定义服务、识别关系、识别包。
对比分析阶段就清楚了:分析的主线是“认定对象、组织对象、描述相互作用、确定操作”四步(教材 7.1.2 在后面还加了一步“定义对象的内部信息”),但不涉及识别包——包是设计阶段才有的组织单位。设计阶段才把属性补全、把服务定义清楚、把类组织成包。
A 是标准的 OOA 四步,直接排除。B 混进了“定义属性”,缺了描述相互作用和识别包。C 混进了分析与设计的内容,也不完整。
这题和真题 55 是一对:55 考分析的四步,56 考设计的五步。把两张清单并排记,比单独背更牢。
十、语言与杂题
对象之间通过(39)方式通信。以下关于好的面向对象程序设计语言的叙述中,不正确的是(40)。
查看答案与解析收起答案与解析
(39)选 A。对象之间通过消息传递通信:一个对象把消息发给另一个对象,接收方根据消息选择自己的操作来响应。B 继承是类之间的关系,C 引用是变量指向对象的方式,D 多态是同一消息的不同响应结果,都不是“通信方式”。
(40)问“不正确的”,选 C。“应该支持通过指针进行引用”不是好的面向对象语言的要求。Java 就没有显式指针,所有对象引用都由虚拟机管理,照样是优秀的面向对象语言;反过来,裸指针会给内存管理带来负担,现代语言普遍在弱化它。
A 支持被封装的对象、B 支持类与实例的概念、D 支持继承和多态,这三条都是面向对象语言的必备特征:没有封装就没有信息隐藏,没有类与实例就没有抽象,没有继承和多态就没有复用与动态分派。
面向对象( )选择合适的面向对象程序设计语言,将程序组织为相互协作的对象集合,每个对象表示某个类的实例。
查看答案与解析收起答案与解析
选 C。“选择合适的面向对象程序设计语言”“将程序组织为相互协作的对象集合”,两个动作都指向编码实现,属于面向对象程序设计(OOP)阶段。
A 分析阶段不选语言,它只关心问题域,产出的模型要独立于实现——这正是真题 49 的 D 选项。B 设计阶段会确定架构和技术选型的方向,但通常不落到“具体用哪个语言写”这种编码层面。D 测试阶段更在后面。
三个阶段的分工可以这样记:OOA 说“做什么”,OOD 说“怎么组织”,OOP 说“用什么语言、写成什么代码”。题干出现了“选择语言”和“组织成对象集合”,只有 OOP 对得上。
下列关于一个类的静态成员的描述中,不正确的是( )。
查看答案与解析收起答案与解析
问“不正确的”,选 D。
D 说“静态数据成员的值不可修改”,错。静态成员的值当然可以改,它的特点是被所有对象共享,而不是“不能改”。改一次,所有对象看到的值都变。真正“不可修改”的是用 final(Java)或 const(C++)修饰的常量。
A 正确:静态方法属于类,没有 this 指针,所以不能直接访问非静态成员,只能访问静态成员。
B 正确:静态数据成员可被该类的所有方法访问,包括静态方法和实例方法。
C 正确:该类的所有对象共享同一份静态数据成员,这也是它别名叫“类变量”的原因。
顺带记一个常考对比:实例变量每个对象一份,静态变量全类一份。
在面向对象技术中,对象具有以下特性:( )。①清晰的边界 ②良好定义的行为 ③确定的位置和数量 ④可扩展性
查看答案与解析收起答案与解析
选 C(①②④)。逐条判断:
① 清晰的边界——是对象的特性。对象是独立的封装单元,有明确边界区分“内”和“外”。
② 良好定义的行为——是。对象通过操作对外提供服务,行为必须明确、可预期。
③ 确定的位置和数量——不是。对象可以在运行时动态创建和销毁,数量随时变化;分布式系统里对象的位置还可能迁移。这条是从传统程序实体硬套过来的。
④ 可扩展性——是。对象可以通过继承、组合等方式扩展能力,这是面向对象的基本优势。
排除③之后只剩 ①②④,选 C。B 把四条全包了,是典型的“全选型”干扰项;D 漏了④。
关于继承,不正确的是(38);关于图中 doIt() 方法,正确的是(39)。
斜体类名为抽象类;实线空心三角为继承,虚线空心三角为实现接口
查看答案与解析收起答案与解析
(38)问“不正确的”,选 D。
D 说“子类可以定义新操作,但不能定义和父类同名的操作”,前半句对、后半句错。子类定义与父类同名同参的操作,正是覆盖(override),是面向对象最核心的机制之一——没有覆盖,多态就无从谈起。
A 正确,一个父类可以有多个子类,这些子类都是父类的特例(特殊化)。
B 正确,父类描述子类的公共属性和操作,这正是把公共部分上移到父类的意义。
C 正确,子类可以继承父类或祖先类的属性和操作,不必自己重写一遍。
(39)选 A。先看清图:Thing1 是接口(标了 <<interface>>),里面声明了 doIt();Thing2、Thing3 用虚线空心三角指向 Thing1,表示它们实现了这个接口;Thing4、Thing5 用实线空心三角指向 Thing2,表示它们继承 Thing2。类名是斜体的 Thing2 和 Thing5 是抽象类。
规则很明确:接口里的方法只有声明没有实现,具体类必须实现它,抽象类可以继续把它保持为抽象,交给子类实现。
逐个套:Thing3 是具体类,直接实现接口,必须实现 doIt();Thing2 是抽象类,可以把 doIt() 留成抽象交给子类;它的子类里 Thing4 是具体类,必须实现 doIt(),而 Thing5 仍是抽象类,可以继续不实现。
所以 A 正确:“doIt() 必须由 Thing3 实现,同时可能由 Thing4 实现”——Thing3 是硬性要求,Thing4 作为具体子类同样必须实现。
B 错在 Thing5 是抽象类,没有实现的义务。C 错在要求 Thing2、Thing5 也实现,抽象类不承担这个义务。D 错在 Thing1 是接口,接口里的方法只有声明、没有实现,谈不上“已经实现”。
在领域类模型中不包含( )。
查看答案与解析收起答案与解析
选 D。领域类模型描述的是领域中的类以及类与类之间的关系,包含三样东西:类的属性(A)、类的操作(B)、类之间的关联(C)。
D“领域对象”不是类模型的组成部分——对象是类的实例,属于运行时的东西。类模型画的是“有哪些类、每个类有什么、类之间怎么连”,不画具体的对象实例。
换个角度理解:类模型是“图纸”,对象是“按图纸造出来的东西”。图纸上不会画出某一台具体的机器,只会画这类机器的规格。所以领域类模型里不会有“领域对象”这一项。
采用面向对象方法进行软件开发,在分析阶段,架构师主要关注系统的( )。
查看答案与解析收起答案与解析
选 D。分析阶段要回答的是“系统做什么”,也就是系统的行为:有哪些功能、在什么条件下做什么、对外表现出什么反应。
A 技术、B 部署、C 实现都是设计、实现阶段才关心的:用什么技术栈是设计决策,部署到几台服务器、怎么集群是部署设计,怎么编码是实现。
这和真题 48 的 D 选项、真题 49 的 C 选项是同一个知识点:分析忽略实现、独立于实现,只关注问题域和行为。
题干里“架构师”三个字容易误导人——架构师当然也管技术和部署,但题目限定了“在分析阶段”,阶段决定关注点,不能按角色想当然。
十一、考前速记
- 实体类存信息、边界类是媒介、控制类管协调。
- 一般—特殊 = 继承(is-a);整体—部分 = 组合/聚合(has-a)。
- 对象 = 对象名 + 属性 + 操作;状态 = 属性 + 当前值。
- 重载:同类、同名、参数不同;覆盖:子类重写父类同名同参方法。
- 封装 = 数据 + 行为绑定 + 信息隐藏;private 只能本类方法访问。
- 继承 = 子类自动拥有父类全部属性和方法,并可新增;多继承可能二义性。
- 多态 = 同一消息、不同响应;靠继承 + 覆盖 + 动态绑定。
- 四种多态:参数(泛型)、包含(子类型)、过载(同名不同义)、强制(类型转换)。
- 静态绑定编译时、动态绑定运行时;多态靠动态绑定。
- 单一职责:一个类一个变化原因。
- 开闭:对扩展开放、对修改关闭。
- 里氏替换:基类出现的地方子类都能替换。
- 依赖倒转:依赖抽象不依赖实现。
- 接口分离:不强迫客户依赖不用的方法。
- 共同重用:重用一个类就要重用整包;共同封闭:一个变化影响整包。
- OOA 四步:认定对象 → 组织对象 → 描述交互 → 确定操作;教材另加“定义对象内部信息”,共 5 个活动。
- OOA 关注问题域(做什么),OOD 关注解决方案(怎么做)。
- 需求描述里的名词 → 对象,动词 → 操作。
十二、答案速查表
| 年份 | 题号 | 答案 | 年份 | 题号 | 答案 |
|---|---|---|---|---|---|
| 2009 上 | 38、39、40 | C、B、A | 2014 下 | 37 | B |
| 2018 下 | 39、40 | B、A | 2020 下 | 38 | D |
| 2009 下 | 37 | B | 2011 下 | 37 | D |
| 2015 下 | 37、38 | A、D | 2018 上 | 37 | A |
| 2015 上 | 39 | A | 2019 上 | 37 | C |
| 2011 下 | 38、39 | D、A | 2011 下 | 42 | B |
| 2012 上 | 38 | A | 2015 上 | 37 | D |
| 2017 下 | 37、38 | C、B | 2019 下 | 37 | D |
| 2020 下 | 37 | D | 2009 下 | 38、39、40 | D、A、C |
| 2010 上 | 37 | D | 2013 下 | 41、42、43 | B、A、C |
| 2016 上 | 37、38 | B、C | 2017 上 | 37、38 | A、D |
| 2017 下 | 39 | D | 2018 下 | 37 | A |
| 2012 下 | 38、39 | D、A | 2013 上 | 37 | C |
| 2014 上 | 39、40 | D、B | 2014 下 | 38 | B |
| 2016 下 | 37 | D | 2017 上 | 40 | A |
| 2018 上 | 40 | D | 2018 下 | 38 | C |
| 2020 下 | 40 | C | 2021 上 | 39、40 | C、D |
| 2010 上 | 38、39、40 | B、D、C | 2012 上 | 39 | B |
| 2014 上 | 38 | C | 2016 下 | 38 | D |
| 2018 上 | 38、39 | D、C | 2019 下 | 40 | A |
| 2009 下 | 42 | D | 2010 下 | 37~42 | B、A、C、D、D、C |
| 2019 上 | 39 | A | 2019 下 | 39 | B |
| 2020 下 | 39 | D | 2021 上 | 38 | C |
| 2021 下 | 38 | D | 2009 上 | 37 | D |
| 2009 下 | 41 | B | 2010 上 | 41 | C |
| 2010 上 | 42 | A | 2011 上 | 37 | C |
| 2016 下 | 39 | C | 2017 下 | 40 | B |
| 2021 上 | 37 | A | 2021 下 | 37 | D |
| 2014 下 | 39、40 | A、C | 2015 上 | 38 | C |
| 2011 上 | 38 | D | 2012 下 | 37 | C |
| 2013 上 | 38、39 | D、A | 2013 下 | 37 | D |
| 2017 上 | 39 | D |
写在最后
面向对象这一章,考的其实是一张“概念地图”:
- 看到“保存信息”想实体类,看到“媒介”想边界类,看到“协调”想控制类。
- 看到“同名不同参”想重载,看到“子类重写”想覆盖,看到“同一消息不同响应”想多态。
- 看到“编译时”想静态绑定,看到“运行时”想动态绑定。
- 看到“扩展开放修改关闭”想 OCP,看到“基类替换”想 LSP,看到“依赖抽象”想 DIP。
把这张地图和速记过两遍,这一章的 3~5 分就是稳的。
祝备考顺利。
还没有评论 — 第一条由你来留。