类与类之间的关系对于理解面向对象具有很重要的作用
- 格式:doc
- 大小:100.50 KB
- 文档页数:5
⾯向对象中类和类的关系在⾯向对象⽅法中,我们在确定了类及类的属性和⽅法后。
不可避免的要研究类和类之间的关系,正是这些关系将整个事情串联起来。
使彼此之间有了联系,就像现实⽣活中,⼈与⼈交往中存在着不同的关系。
了解这些关系,对于我们开发系统百利⽽⽆⼀害,能够让我们轻松、⾼效的⼯作,相同像我们在⽇常⽣活中处理好⼈与⼈之间的关系。
会给我们带来巨⼤的优点。
那么我们就来认识⼀下。
⾯向对象中类与类之间有那些关系。
类和类之间的关系⼤概能够分为⼀下⼏种类型:泛化关系(Generalization)、实现关系(realization)、依赖关系(Dependency)、关联关系(Association)(关联、聚合(Aggregation)、组合(Composition))。
泛化关系和实现关系体现的是⼀种类和类、或者类和接⼝间的关系。
不存在引⽤,归结为纵向关系。
依赖关系和关联关系体现的是类和类、类与接⼝间的引⽤。
归结为横向关系。
⼀、泛化关系泛化关系是⼀个类(⼦类、⼦接⼝)继承另外的⼀个类(⽗类、⽗接⼝)的功能,⽽且能够有⾃⼰的新功能。
也既是我们所说的继承关系。
在java中通过extends来标识。
在UML中⽤⼀条带空⼼箭头的实现表⽰,从⼦类指向⽗类,或者⼦接⼝指向⽗接⼝。
代码例如以下:Class _A{}Class _B extends _A{}Public class Test{Public static void main(String args[]){_A a = new _B();}}⼆、实现关系实现关系指的是class类实现interface接⼝(能够使多个接⼝)。
在java中⽤implements标识,在UML中⽤⼀条带空⼼三⾓箭头的虚线标识,从类指向实现的接⼝。
代码例如以下:Interface A{}Class B implements A{}Public class Test{Public static void main( String args[] ){B b = new B();}}说明:以上泛化和实现为⼀对,两者都⽤空⼼三⾓形。
怎样使用类和对象使用类和对象是面向对象编程的核心概念之一、类是一种抽象的数据类型,它定义了一类对象的共同属性和方法。
而对象则是类的具体实例,通过实例化一个类,我们可以创建出多个对象。
使用类和对象能够有效地组织和管理代码,提高代码的可读性和可维护性。
下面我们将从定义类和对象、实例化对象、访问属性和方法、类的继承以及类之间的关系等方面来详细介绍如何使用类和对象。
一、定义类和对象在Python中,我们可以使用关键字class来定义一个类,类的命名通常采用首字母大写的驼峰命名法。
类内可以定义属性和方法,属性是类的状态信息,而方法则是类的行为。
例如,我们定义一个名为Person的类,其中包含一个属性name和一个方法greeting:```class Person:def __init__(self, name): = namedef greeting(self):print("Hello, my name is", )```上述代码中,__init__方法是一个特殊的方法,它用来初始化类的实例。
self参数代表类的实例本身,通过self我们可以访问类的属性和方法。
二、实例化对象在定义了一个类之后,我们可以通过调用类来实例化一个对象。
在Python中,对象的实例化操作非常简单,只需要使用类名后跟上一对括号即可。
例如,我们实例化一个名为Tom的Person对象,并调用其greeting方法:```tom = Person("Tom")tom.greeting```代码执行结果为:Hello, my name is Tom三、访问属性和方法访问类的属性和方法通过使用点运算符(.)来实现。
在Python中,类的属性和方法的访问和调用方式是一样的,都是通过对象名后面跟上一对括号来实现。
例如,我们使用前面定义的Person类,实例化一个名为Tom的对象,并访问其name属性和调用greeting方法:```tom = Person("Tom")print()tom.greeting```代码执行结果为:TomHello, my name is Tom四、类的继承在面向对象编程中,继承使得一个类可以继承另一个类的属性和方法,从而得到更多的功能。
《软件工程》练习题一、判断题1.螺旋模型是在瀑布模型和增量模型的基础上增加了风险分析活动。
(对)2.数据字典是对数据流图中的数据流,加工、数据存储、数据的源和终点进行详细定义。
(错)3.JAVA语言编译器是一个CASE工具.(对)。
4.软件是指用程序设计语言(如PASCAL ,C,VISUAL BASIC 等)编写的程序,软件开发实际上就是编写程序代码。
(错)5.软件模块之间的耦合性越弱越好。
(对)6.数据库设计说明书是一个软件配置项(对)7.在面向对象的软件开发方法中,每个类都存在其相应的对象,类是对象的实例,对象是生成类的模板.(错)8.过程描述语言可以用于描述软件的系统结构。
(错)9.如果通过软件测试没有发现错误,则说明软件是正确的.(错)10.快速原型模型可以有效地适应用户需求的动态变化。
(对)11.模块化,信息隐藏,抽象和逐步求精的软件设计原则有助于得到高内聚,低耦合度的软件产品。
(对)12.集成测试主要由用户来完成。
(错)13.确认测试计划应该在可行性研究阶段制定(错)14.白盒测试无需考虑模块内部的执行过程和程序结构,只要了解模块的功能即可.(错)15.软件概要设计包括软件系统结构设计以及数据结构和数据库设计。
(对)16.用例常被用在项目的需求分析阶段,对项目的测试计划和用户指南也有用处。
(对)二、单选题1.瀑布模型的关键不足在于(2)(1)过于简单(2)不能适应需求的动态变更(3)过于灵活(4)各个阶段需要进行评审2.在面向对象软件开发方法中,类与类之间主要有以下结构关系(1)(1)关联和泛化(2)继承和一般(3)聚集和消息传递(4)继承和方法调用3.以下哪一项不是软件危机的表现形式(3)(1)成本高(2)生产率低(3)技术发展快(4)质量得不到保证4.以下哪一项不是面向对象的特征(4)(1)多态性(2)继承性(3)封装性(4)过程调用5.面向对象模型主要由以下哪些模型组成(1)(1)对象模型、动态模型、功能模型(2)对象模型、数据模型、功能模型(3)数据模型、动态模型、功能模型(4)对象模型、动态模型、数据模型6.软件可行性研究一般不考虑(4)(1)是否有足够的人员和相关的技术来支持系统开发(2)是否有足够的工具和相关的技术来支持系统开发(3)待开发软件是否有市场、经济上是否合算(4)待开发的软件是否会有质量问题7.软件维护的副作用主要有以下哪几种(3)(1)编码副作用、数据副作用、测试副作用(2)编码副作用、数据副作用、调试副作用(3)编码副作用、数据副作用、文档副作用(4)编码副作用、文档副作用、测试副作用8.软件项目计划一般不包括以下哪项内容(4)(1)培训计划(2)人员安排(3)进度安排(4)软件开发标准的选择和制定9.以下哪一项不属于面向对象的软件开发方法(3)(1)coad方法(2)booch方法(3)jackson方法(4)omt方法10.以下哪种测试方法不属于白盒测试技术(2)(1)基本路径测试(2)边界值分析测试(3)循环覆盖测试(4)逻辑覆盖测试11.需求规格说明书的作用不应该包括(D)。
UML类图及类与类之间的关系原⽂地址:类图⽤于描述系统中所包含的类以及它们之间的相互关系,帮助⼈们简化对系统的理解,它是系统分析和设计阶段的重要产物,也是系统编码和测试的重要模型依据。
1. 类类(Class)封装了数据和⾏为,是⾯向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。
在系统中,每个类都具有⼀定的职责,职责指的是类要完成什么样的功能,要承担什么样的义务。
⼀个类可以有多种职责,设计得好的类⼀般只有⼀种职责。
在定义类的时候,将类的职责分解成为类的属性和操作(即⽅法)。
类的属性即类的数据职责,类的操作即类的⾏为职责。
设计类是⾯向对象设计中最重要的组成部分,也是最复杂和最耗时的部分。
在软件系统运⾏时,类将被实例化成对象(Object),对象对应于某个具体的事物,是类的实例(Instance)。
类图(Class Diagram)使⽤出现在系统中的不同类来描述系统的静态结构,它⽤来描述不同的类以及它们之间的关系。
在系统分析与设计阶段,类通常可以分为三种,分别是实体类(Entity Class)、控制类(Control Class)和边界类(Boundary Class),下⾯对这三种类加以简要说明:(1) 实体类:实体类对应系统需求中的每个实体,它们通常需要保存在永久存储体中,⼀般使⽤数据库表或⽂件来记录,实体类既包括存储和传递数据的类,还包括操作数据的类。
实体类来源于需求说明中的名词,如学⽣、商品等。
(2) 控制类:控制类⽤于体现应⽤程序的执⾏逻辑,提供相应的业务操作,将控制类抽象出来可以降低界⾯和数据库之间的耦合度。
控制类⼀般是由动宾结构的短语(动词+名词)转化来的名词,如增加商品对应有⼀个商品增加类,注册对应有⼀个⽤户注册类等(3) 边界类:边界类⽤于对外部⽤户与系统之间的交互对象进⾏抽象,主要包括界⾯类,如对话框、窗⼝、菜单等。
在⾯向对象分析和设计的初级阶段,通常⾸先识别出实体类,绘制初始类图,此时的类图也可称为领域模型,包括实体类及其它们之间的相互关系。
每小题2分,共70分第1题:以下关于虚函数的叙述中不正确的是()。
A.虚函数属于成员函数B.虚函数不允许说明成静态的C.凡是虚函数必须用virtual说明D.虚函数可以被继承【正确答案】:C【参考解析】:虚函数的引入是为了解决动态绑定问题.使类的实例表现出多态性,虚函数在继承后依然保持虚函数特性,此时不需要用virtual关键词修饰。
第2题:A【参考解析】:本题主要考察setfill的用法。
只用在设置了宽度的情况下,字符填充操作setfill才有意义。
另外要注意的是设置宽度setw是所有格式中惟一一个一次有效的设置。
第3题:下述说法错误的是()。
A.对象之间不可以相互赋值B.对象可以用作函数参数C.对象可以用作数组的元素D.对象可以用作另一对象的成员【正确答案】:A【参考解析】:如果重载了赋值运算符后,对象之间是可以赋值的,对象如C++中其他内置的数据类型一样,可以作为函数参数、数组元素,其他对象的成员存在。
第4题:假定AB为一个类,则执行AB x;语句时将自动调用该类的()。
A.有参构造函数B.无参构造函数C.拷贝构造函数D.赋值重载函数【正确答案】:B【参考解析】:当没有显式调用指定形式的构造函数。
系统自动调用无参构造函数,如果没有为类指定此构造函数,则系统自动为其生成一个最简单的无参构造函数。
)。
A)654321B)432156C)456123D)123456【正确答案】:A【参考解析】:本题采用递归函数的方式将数组中的元素进行倒置,只要能够看出函数fun的功能,即可以得出正确答案为A。
第6题:数据库概念设计中,由分散到集中的设计方法是()。
A.视图设计B.视图集成设计C.集中式模式设计D.分数式模式设计【参考解析】:数据库概念设计中,由分散到集中的设计方法是视图集成设计。
第7题:类的构造函数的作用是()。
A.一般成员函数B.类的初始化C.对象的初始化D.删除对象创建的所有对象【正确答案】:C【参考解析】:本题考查类的构造函数的作用,构造函数一般负责完成对象建立时的初始化工作,如资源的分配。
类与类之间的六种关系在面向对象编程中,类与类之间有六种关系,分别是继承、实现、聚合、组合、关联和依赖。
这些关系描述了不同类之间的联系和依赖,有助于我们更好地设计和组织程序。
继承是一种类与类之间的关系,它描述了一个类从另一个类继承属性和方法的过程。
继承可以减少代码的重复,提高代码的可维护性和可扩展性。
例如,一个动物类可以作为其他类的父类,其他类可以继承动物类的属性和方法,如狗类、猫类等。
实现是一种类与接口之间的关系,它描述了一个类实现接口的过程。
接口定义了一组方法,实现了接口的类必须实现这些方法。
实现可以使代码更加灵活,可以在不同的类中实现相同的接口,从而实现代码的复用。
聚合是一种“整体-部分”的关系,它描述了一个类包含其他类的实例的过程。
聚合表示一种弱的“拥有”关系,即一个类可以包含多个其他类的实例,但这些实例可以独立存在。
例如,一个汽车类可以包含多个轮子类的实例,但轮子类的实例可以独立存在。
组合是一种“整体-部分”的关系,它描述了一个类包含其他类的实例,并且这些实例不能独立存在的过程。
组合表示一种强的“拥有”关系,即一个类包含其他类的实例,这些实例不能独立存在。
例如,一个房子类可以包含多个房间类的实例,但房间类的实例不能独立存在。
关联是一种类与类之间的关系,它描述了一个类与另一个类之间的联系。
关联可以是单向的或双向的,可以是强的或弱的。
例如,一个人类可以与一个手机类之间存在关联,表示这个人拥有这个手机。
依赖是一种类与类之间的关系,它描述了一个类依赖于另一个类的过程。
依赖表示一个类使用了另一个类的实例或方法,但不拥有这个实例或方法。
例如,一个人类可以依赖于一个汽车类的实例,表示这个人需要使用这个汽车来出行。
类与类之间的六种关系描述了不同类之间的联系和依赖,有助于我们更好地设计和组织程序。
在实际编程中,我们需要根据具体情况选择不同的关系,以实现代码的复用、可维护性和可扩展性。
1.在某系统中,存在如下的业务陈述:①一个客户提交0个或多个订单;②一个订单由一个且仅由一个客户提交。
系统中存在两个类:“客户”类和“订单”类。
对应每个“订单”类的实例,存在【 B 】“客户”类的实例;对应每个“客户”类的实例,存在0个或多个“客户”类的实例。
A)0个B)1个C)1个或多个D)0个或多个2.一般地,可以将软件开发的生命周期划分为问题定义、可行性分析、【 C 】、总体设计、详细设计、编码和单元测试、综合测试和维护8个阶段。
A)项目论证B)初始调查C)需求分析与定义D)问题分析3.下列关于软件开发瀑布模型的说法中,正确的是【 A 】: A)必须等前一阶段的工作完成之后,才能开始后一阶段的工作。
B)前一阶段的输出文档对后一阶段影响不大。
C)可以先完成软件的编码工作再补充相关文档。
D)以上说法都不对。
4.下列叙述中,与提高软件可移植性相关的是【 D 】:A)选择时间效率高的算法 B)尽可能减少注释 C)选择空间效率高的算法 D)尽量用高级语言编写系统中对效率要求不高的部分5.在信息系统分析阶段,对数据流图的改进,包括检查数据流图的正确性和提高数据流图的易理解性,下面说法不正确的是【 A 】。
A)数据流图中,输入数据与输出数据必须匹配B)数据流图的父图和子图必须平衡C)任何一个数据流至少有一端是处理框D)数据流图中适当的命名,可以提高易理解性6.【 A 】是导致软件缺陷的最大原因。
A)需求规格说明书B)设计方案C)编写代码D)测试计划7.从事物的组成部件及每个部件的属性、功能来认识事物。
这种方法被称为【 A 】的方法。
A)面向对象B)面向数据C)面向过程D)面向属性8.在软件项目管理中可以使用各种图形工具来辅助决策,下面对Gantt 图的描述中,不正确的是【 C 】。
A)Gantt图表现了各个活动的持续时间B)Gantt图表现了各个活动的起始时 C Gantt图反映了各个活动之间依赖关系D)Gantt图表现了完成各个活动的进度9.下列选项中,【 C 】不属于结构化分析方法所使用的工具。
类图知识点总结类图是面向对象系统建模中最为常用的一种结构化图表,它描述了系统中的类以及它们之间的关系。
类图可以帮助开发人员更好地理解系统结构,预判系统行为,促进团队协作和代码编写。
在软件开发过程中,类图通常是首先绘制的概念图,也是软件设计中最为基本的设计工具之一。
通过对类图的学习和掌握,可以帮助开发人员更好地进行软件设计与开发工作。
以下是类图的基本知识点总结:1. 类与对象类是描述系统中具有相似特征和行为的对象的模板,它包含了一组数据和方法,用来描述这些对象的状态和行为。
而对象是类的一个实例化,是类的具体实体。
在类图中,类通常用一个矩形表示,类名位于矩形的顶部,类的属性和方法则分别位于矩形的中间和底部。
2. 类之间的关系在类图中,类之间的关系分为以下几种:- 关联关系:表示两个类之间存在某种关联,通常用一条实线连接两个类,箭头指向被关联的类。
关联关系可以有多重性,如一对一、一对多、多对多等。
- 聚合关系:表示整体与部分的关系,通常由一个包含整体的类指向被包含的部分类,聚合关系用一条实线连接两个类,并在整体端画一个空心菱形。
- 组合关系:表示整体负责部分的生命周期,通常由一个包含整体的类指向被包含的部分类,组合关系也用一条实线连接两个类,但在整体端画一个实心菱形。
- 继承关系:表示父类与子类之间的关系,通常由一个三角箭头指向父类,继承关系用一条带有空心三角箭头的实线连接父类和子类。
- 实现关系:表示类实现某个接口,通常由一个带有虚线箭头的实线连接类和接口。
3. 类图的组成元素类图主要由以下几种组成元素构成:- 类:用矩形表示,包括类名、属性和方法。
- 接口:用和类相似的方式表示,但通常在类的矩形上方加上“<<interface>>”标识。
- 关联关系:用实线连接两个类。
- 聚合关系:用一条实线连接两个类,并在整体端画一个空心菱形。
- 组合关系:用一条实线连接两个类,并在整体端画一个实心菱形。
类组合聚合-概述说明以及解释1.引言1.1 概述概述在面向对象编程中,类、组合和聚合是重要的概念。
类是面向对象编程的基本组成单位,它描述了对象的属性和行为。
组合和聚合则是描述类之间关系的方式。
组合和聚合都指的是类之间的关联关系,它们描述的是一种整体与部分的关系。
在组合关系中,一个类是另一个类的整体,整体的生命周期完全控制着部分的生命周期;而在聚合关系中,一个类是另一个类的部分,部分的生命周期可以独立于整体存在。
通过组合和聚合,我们可以将多个类组织在一起,形成更加复杂的系统。
组合关系在模型的层次化组织中非常常见,它可以让我们构建起一个有层次结构的系统,使系统的结构更加清晰、易于理解。
聚合关系则更加强调类之间的独立性和灵活性,它可以让我们在需要时动态地组合类,使系统更加灵活、可扩展。
本文将对类、组合和聚合进行深入探讨,详细介绍它们的定义、特点和应用。
我们将从类的概念和特点开始,了解类的基本组成和作用。
然后,我们将深入讨论组合关系,探究其定义和在实际应用中的使用场景。
最后,我们将总结类和组合的关系,并探讨聚合的重要性。
通过阅读本文,您将对类、组合和聚合有更深入的理解,能够更灵活地运用它们来构建复杂的系统。
接下来,我们将开始探讨类的概念和特点。
1.2文章结构文章结构是指文章的组织框架,它能够使读者更好地理解和掌握文章的内容。
在本文中,我们将按照以下结构展开讨论:1. 引言:介绍文章的背景和目的,总结后续章节的内容,引起读者的兴趣。
2. 正文部分:分为两个主要章节,分别讨论类的概念和特点以及组合的定义和应用。
2.1 类的概念和特点:首先介绍什么是类,类作为面向对象编程的基本概念是如何定义和解释的。
接着详细讨论类的特点,如封装性、继承性和多态性,以及它们在软件开发中的重要性和应用。
2.2 组合的定义和应用:首先明确什么是组合,组合又与类之间有怎样的关系。
然后探讨组合在面向对象编程中的应用场景,如组合关系的建立、组合关系的表示方法等。
面向对象程序设计复习资料第2章面向对象思维建立面向对象程序设计的特征:①模块化;②抽象化;③封装;④可组合;⑤继承;⑥软件持续使用时间更长。
面向对象思维分为两步:一是需求分析,识别出有哪些对象,它们分别做什么事(who&&what);二是如何利用对象协作完成一件完整的事情(how)。
·类与对象的概念和关系:1)类是面向对象程序设计方法的核心,利用类可以实现对数据的封装和隐蔽。
在面向对象程序设计中,程序模块是由类构成。
类是对逻辑相关的函数与数据的封装,它是对问题的抽象描述。
C++的语法提供了对自定义类型的支持,这就是类。
正如基本数据类型中隐含的数据和操作,因此在定义一个类时也要说明数据和操作。
2)类实际上是一种抽象机制,它描述了一类为问题的属性和行为,即类描述了一类对象的数据存储和操作特征。
每一个怪物都有一些共同的静态特征,这些共同的特征抽象到类中,统称为该类的属性,属性通过声明普通变量来实现。
每一个怪物都有一些共同的动态行为,这些共同的行为抽象到类中,统称为该类的操作,操作通过声明普通变量来实现。
怪物类伪类图:第3章面向对象思维建模UML:统一建模语言或标准建模语言1)类图:常见的UML图,显示了建模的静态结构,特别是模型中存在的类、类的内部结构以及他们与其他类的关系等。
类与类之间的常见关系:①依赖关系:依赖关系的偶然性和临时性——人依赖船②聚合关系:整体与部分之间是可分离的③继承关系:含义:儿子类继承父亲类,不仅继承所有属性和行为,还自己拓展2)时序图:也称为序列图或循序图或顺序图,是一种UML交互图,它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。
类图表示“不因时间而变化的部分(静态关系)”;时序图表示“随时间而变化的部分(动态行为)”时序图的元素组成和绘制流程:对象:类的实例;三种状态——激活、运行、销毁生命线:对象在一段时间内的存在激活:对象操作的执行消息:对象之间的通信机制(五类:递归调用、普通操作、返回消息、导步调用)3)用例图:指由参与者、用例以及他们之间的关系构成的用于描述系统功能的视图。
类与类之间的关系⼀. 类与类之间的依赖关系⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进⾏归类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类中存在以下关系: 1. 依赖关系 2. 关联关系 3. 组合关系 4. 聚合关系 5. 继承关系 6. 实现关系由于python是⼀⻔弱类型编程语⾔. 并且所有的对象之间其实都是多态的关系. 也就是说,所有的东⻄都可以当做对象来使⽤. 所以我们在写代码的时候很容易形成以上关系. ⾸先. 我们先看第⼀种, 也是这些关系中紧密程度最低的⼀个, 依赖关系.⾸先, 我们设计⼀个场景. 还是最初的那个例⼦. 要把⼤象装冰箱. 注意. 在这个场景中, 其实是存在了两种事物的. ⼀个是⼤象, ⼤象负责整个事件的掌控者, 还有⼀个是冰箱, 冰箱负责被⼤象操纵.⾸先, 写出两个类, ⼀个是⼤象类, ⼀个是冰箱类.class Elphant:def__init__(self, name): = namedef open(self):'''开⻔:return :return:'''passdef close(self):'''关⻔:return :return:'''passclass Refrigerator:def open_door(self):print("冰箱⻔被打开了")def close_door(self):print("冰箱⻔被关上了")冰箱的功能⾮常简单, 只要会开⻔, 关⻔就⾏了. 但是⼤象就没那么简单了. 想想. ⼤象开⻔和关⻔的时候是不是要先找个冰箱啊. 然后呢? 打开冰箱⻔. 是不是打开刚才找到的那个冰箱⻔. 然后装⾃⼰. 最后呢? 关冰箱⻔, 注意, 关的是刚才那个冰箱吧. 也就是说. 开⻔和关⻔⽤的是同⼀个冰箱. 并且. ⼤象有更换冰箱的权利, 想进那个冰箱就进那个冰箱. 这时, ⼤象类和冰箱类的关系并没有那么的紧密. 因为⼤象可以指定任何⼀个冰箱. 接下来. 我们把代码完善⼀下.class Elphant:def__init__(self, name): = namedef open(self, ref):print("⼤象要开⻔了. 默念三声. 开!")# 由外界传递进来⼀个冰箱, 让冰箱开⻔. 这时. ⼤象不⽤背着冰箱到处跑.# 类与类之间的关系也就不那么的紧密了. 换句话说. 只要是有open_door()⽅法的对象. 都可以接收运⾏ref.open_door()def close(self, ref):print("⼤象要关⻔了. 默念三声. 关!")passdef take(self):print("钻进去")class Refrigerator:def open_door(self):print("冰箱⻔被打开了")def close_door(self):print("冰箱⻔被关上了")# 造冰箱r = Refrigerator()# 造⼤象el = Elphant("神奇的⼤象")el.open(r) # 注意. 此时是把⼀个冰箱作为参数传递进去了. 也就是说. ⼤象可以指定任何⼀个冰箱.el.take()el.close(r)此时, 我们说, ⼤象和冰箱之间就是依赖关系. 我⽤着你. 但是你不属于我. 这种关系是最弱的.⽐如. 公司和雇员之间. 对于正式员⼯, 肯定要签订劳动合同. 还得⼩⼼伺候着. 但是如果是兼职. 那⽆所谓. 需要了你就来. 不需要你就可以拜拜了. 这⾥的兼职(临时⼯) 就属于依赖关系.我⽤你. 但是你不属于我.⼆. 关联关系.组合关系, 聚合关系其实这三个在代码上写法是⼀样的. 但是, 从含义上是不⼀样的. 1. 关联关系. 两种事物必须是互相关联的. 但是在某些特殊情况下是可以更改和更换的. 2. 聚合关系. 属于关联关系中的⼀种特例. 侧重点是xxx和xxx聚合成xxx. 各⾃有各⾃的 声明周期. ⽐如电脑. 电脑⾥有CPU, 硬盘, 内存等等. 电脑挂了. CPU还是好的. 还是 完整的个体 3. 组合关系. 属于关联关系中的⼀种特例. 写法上差不多. 组合关系⽐聚合还要紧密. ⽐ 如⼈的⼤脑, ⼼脏, 各个器官. 这些器官组合成⼀个⼈. 这时. ⼈如果挂了. 其他的东⻄ 也跟着挂了.⾸先我们看关联关系: 这个最简单. 也是最常⽤的⼀种关系. ⽐如. ⼤家都有男⼥朋友. 男⼈关联着⼥朋友. ⼥⼈关联着男朋友. 这种关系可以是互相的, 也可以是单⽅⾯的.class Boy:def__init__(self, name, girlFriend=None): = nameself.girlFriend = girlFrienddef have_a_dinner(self):if self.girlFriend:print("%s 和 %s⼀起去吃晚餐" % (, ))else:print("单⾝狗. 吃什么饭")class Girl:def__init__(self, name): = nameb = Boy("alex")b.have_a_dinner()# 突然⽜B了. 找到⼥朋友了g = Girl("如花")b.girlFriend = g # 有⼥朋友了. 6666b.have_a_dinner()gg = Girl("李⼩花")bb = Boy("wusir", gg) # 娃娃亲. 出⽣就有⼥朋友. 服不服bb.have_a_dinner() # 多么幸福的⼀家# 突然.bb失恋了. 娃娃亲不跟他好了bb.girlFriend = Nonebb.have_a_dinner() # ⼜单⾝了.注意. 此时Boy和Girl两个类之间就是关联关系. 两个类的对象紧密练习着. 其中⼀个没有了. 另⼀个就孤单的不得了. 关联关系, 其实就是我需要你. 你也属于我. 这就是关联关系. 像这样的关系有很多很多. ⽐如. 学校和⽼师之间的关系.School --- 学校Teacher--- ⽼师⽼师必然属于⼀个学校. 换句话说. 每个⽼师肯定有⼀个指定的⼯作机构. 就是学校. 那⽼师的属性中必然关联着学校.class School:def__init__(self, name, address): = nameself.address = addressclass Teacher:def__init__(self, name, school=None): = nameself.school = schools1 = School("⽼男孩北京校区", "美丽的沙河")s2 = School("⽼男孩上海校区", "迪⼠尼旁边")s3 = School("⽼男孩深圳校区", "南⼭区法院欢迎你")t1 = Teacher("⾦王", s1)t2 = Teacher("银王", s1)t3 = Teacher("海峰", s2)t4 = Teacher("⾼鑫", s3)# 找到⾼鑫所在的校区地址print(t4.school.address)想想, 这样的关系如果反过来. ⼀个⽼师可以选⼀个学校任职, 那反过来. ⼀个学校有多少⽼师呢? ⼀堆吧? 这样的关系如何来描述呢?def__init__(self, name, address): = nameself.address = addressself.t_list = [] # 每个学校都应该有⼀个装⼀堆⽼师的列表def add_teacher(self, teacher):self.t_list.append(teacher)class Teacher:def__init__(self, name, school=None): = nameself.school = schools1 = School("⽼男孩北京校区", "美丽的沙河")s2 = School("⽼男孩上海校区", "迪⼠尼旁边")s3 = School("⽼男孩深圳校区", "南⼭区法院欢迎你")t1 = Teacher("⾦王", s1)t2 = Teacher("银王", s1)t3 = Teacher("海峰", s2)t4 = Teacher("⾼鑫", s3)s1.add_teacher(t1)s1.add_teacher(t2)s1.add_teacher(t3)# 查看沙河校区有哪些⽼师for t in s1.t_list:print()好了. 这就是关联关系. 当我们在逻辑上出现了. 我需要你. 你还得属于我. 这种逻辑就是关联关系. 那注意. 这种关系的紧密程度⽐上⾯的依赖关系要紧密的多. 为什么呢? 想想吧⾄于组合关系和聚合关系. 其实代码上的差别不⼤. 都是把另⼀个类的对象作为这个类的属性来传递和保存. 只是在含义上会有些许的不同⽽已.三. 继承关系.在⾯向对象的世界中存在着继承关系. 我们现实中也存在着这样的关系. 我们说过. x是⼀种y, 那x就可以继承y. 这时理解层⾯上的. 如果上升到代码层⾯. 我们可以这样认为. ⼦类在不影响⽗类的程序运⾏的基础上对⽗类进⾏的扩充和扩展. 这⾥.我们可以把⽗类被称为超类或者基类. ⼦类被称为派⽣类.⾸先, 类名和对象默认是可以作为字典的key的class Foo:def__init__(self):passdef method(self):pass# __hash__ = Noneprint(hash(Foo))print(hash(Foo()))既然可以hash. 那就是说字典的key可以是对象或者类dic = {}dic[Foo] = 123dic[Foo()] = 456print(dic) # {<class '__main__.Foo'>: 123, <__main__.Foo object at0x103491550>: 456}虽然显⽰的有点⼉诡异. 但是是可以⽤的.接下来. 我们来继续研究继承上的相关内容. 在本节中主要研究⼀下self. 记住. 不管⽅法之间如何进⾏调⽤. 类与类之间是何关系. 默认的self都是访问这个⽅法的对象.class Base:def__init__(self, num):self.num = numdef func1(self):print(self.num)class Foo(Base):passobj = Foo(123)obj.func1() # 123 运⾏的是Base中的func1继续:class Base:def__init__(self, num):self.num = numdef func1(self):print(self.num)class Foo(Base):def func1(self):print("Foo. func1", self.num)obj.func1() # Foo. func1 123 运⾏的是Foo中的func1再来:class Base:def__init__(self, num):self.num = numdef func1(self):print(self.num)self.func2()def func2(self):print("Base.func2")class Foo(Base):def func2(self):print("Foo.func2")obj = Foo(123)obj.func1() # 123 Foo.func2 func1是Base中的 func2是⼦类中的总结. self在访问⽅法的顺序: 永远先找⾃⼰的. ⾃⼰的找不到再找⽗类的.接下来. 来难得:class Base:def__init__(self, num):self.num = numdef func1(self):print(self.num)self.func2()def func2(self):print(111, self.num)class Foo(Base):def func2(self):print(222, self.num)lst = [Base(1), Base(2), Foo(3)]for obj in lst:obj.func2() # 111 1 | 111 2 | 222 3再来. 还不够绕.class Base:def__init__(self, num):self.num = numdef func1(self):print(self.num)self.func2()def func2(self):print(111, self.num)class Foo(Base):def func2(self):print(222, self.num)lst = [Base(1), Base(2), Foo(3)]for obj in lst:obj.func1() # 那笔来吧. 好好算结论: self就是你访问⽅法的那个对象. 先找⾃⼰, 然后在找⽗类的.四. 类中的特殊成员什么是特殊成员呢? __init_()就是⼀个特殊的成员. 说⽩了. 带双下划线的那⼀坨. 这些⽅法在特殊的场景的时候会被⾃动的执⾏. ⽐如, 1. 类名() 会⾃动执⾏__init__() 2. 对象() 会⾃动执⾏__call__() 3. 对象[key] 会⾃动执⾏__getitem__() 4. 对象[key] = value 会⾃动执⾏__setitem__() 5. del 对象[key] 会⾃动执⾏ __delitem__() 6. 对象+对象会⾃动执⾏ __add__() 7. with 对象 as 变量会⾃动执⾏__enter__ 和__exit__ 8. 打印对象的时候会⾃动执⾏ __str__ 9. ⼲掉可哈希 __hash__ == None 对象就不可哈希了.创建对象的真正步骤:⾸先, 在执⾏类名()的时候. 系统会⾃动先执⾏__new__()来开辟内存. 此时新开辟出来的内存区域是空的. 紧随其后, 系统⾃动调⽤__init__()来完成对象的初始化⼯作. 按照时间轴来算. 1. 加载类 2. 开辟内存(__new__) 3. 初始化(__init__) 4. 使⽤对象⼲xxxxxxxxx类似的操作还有很多很多. 我们不需要完全刻意的去把所有的特殊成员全都记住. 实战中也⽤不到那么多. ⽤到了查就是了.。
类与类之间的关系--泛化,关联,依赖,实现类,对象是⾯向对象的基础,类与类之间的关系是⾯向对象不可或缺的⼀部分。
以下将从类的关系定义,UML中的符号表⽰,代码实现三⽅⾯介绍类与类之间的关系。
1、泛化(Generalization):也成为继承关系。
指⼀个类(⼦类或者⼦接⼝)继承另外⼀个类(⽗类或者⽗接⼝)的功能。
并能够添加⾃⼰的功能。
在程序程序中⽤keywordextends明⽩标识,在UML设计中⽤空三⾓和实线表⽰。
从⼦类指向⽗类。
或者⼦接⼝指向⽗接⼝。
如图代码:public class Cat {public Cat(){}public void Eat(){}public void Run(){}public void Walk(){}}⼦类演⽰样例public class WhiteCat extends Cat {public WhiteCat(){}public void Eat(){}public void Run(){}public void Walk(){}}2、实现(Realize)是指⼀个class 实现interface接⼝的功能,⽤keywordimplements标识。
在UML设计中⽤⼀条带空⼼箭头的虚线表⽰,箭头指向接⼝。
如图代码:public interface Iaction {public void drink();public void eat();}public class dog implements Iaction {public dog(){}public void finalize() throws Throwable {}public void drink(){}public void eat(){}}3、依赖(Dependency)是指⼀个类A使⽤到了还有⼀个类B,⽽这样的使⽤关系是具有偶然性、暂时性。
可是类B的变化会影响到类A。
表如今代码层⾯,为类B作为參数被类A在某个⽅法中使⽤。
面向对象分析与设计方法面向对象分析与设计方法(Object-oriented Analysis and Design,简称OOAD)是一种用于系统开发的方法论,它倡导通过抽象和模块化的方式来分析和设计系统。
在软件开发领域,面向对象的方法已经成为主流,它具有良好的可维护性、可扩展性和可重用性。
一、面向对象分析(Object-oriented Analysis)面向对象分析是软件开发过程的第一步,它主要涉及到研究问题域并确定需求。
在面向对象分析阶段,开发团队与用户和领域专家进行密切合作,以确保对问题域的深入理解。
这一阶段的重要任务包括:1. 需求收集与分析:通过与客户和用户的交流,明确系统的功能需求和业务流程。
分析师可以使用各种技术(如访谈、问卷调查、观察等)来获取准确的需求。
2. 领域建模:通过对问题域的建模,深入理解业务领域的概念、业务规则和相关过程。
建模工具如UML(统一建模语言)可以被用来表示领域模型。
3. 构建用例模型:用例模型是对系统功能需求的描述,它描述了系统与外部参与者之间的交互。
用例模型可以帮助开发团队明确系统的边界和关键功能。
二、面向对象设计(Object-oriented Design)在面向对象设计阶段,分析师通过对需求的深入理解和领域模型的基础上,开始设计系统的结构和组织。
设计的目标是构建一个高效、灵活和可扩展的系统。
以下是面向对象设计的主要任务:1. 构建类模型:类是面向对象系统中最基本的构建块。
在设计阶段,分析师需要根据领域模型和需求,识别出系统中的类,并定义它们的属性和行为。
2. 定义类之间的关系:在面向对象系统中,类之间的关系非常重要。
通过定义关联、继承、聚合和依赖等关系,可以更好地组织系统的结构,使系统具有更好的灵活性和可扩展性。
3. 定义接口和协议:接口和协议定义了类之间的合作方式,它们定义了类的公共方法和行为。
通过良好的接口设计,可以实现系统模块的解耦合,提高系统的可维护性和可重用性。
类与类之间的关系对于理解面向对象具有很重要的作用,下面进行总结!一、类与类之间存在以下关系:UML图与应用代码例子:1. 泛化(Gen eralizatio n)[泛化]表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。
一般化的关系是从子类指向父类的,与继承或实现的方法相反。
[简单理解]是一个is a 的关系。
如老虎是一个动物[具体表现]父类父类实例二new子类()[UML 图](图 1.1)Animal/Tiger Dug图1.1 Animal类与Tiger类,Dog类的泛化关系[代码表现]1. class Ani mal{2.2. }3. class Tiger exte nds An imal {5.4. }5. public class Test6. {7. public void test()8. {9. An imal a=new Tiger();13. }10. } 13. }8. }2. 依赖(Depe nde ncy)[依赖]对于两个相对独立的对象,当一个对象负责构造另一个对象的实例, 或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。
[具体表现]依赖关系表现在 局部变量,方法的参数,以及对静态方法的调用[简单理解]一个类使用了另外一个类作为局部变量和方法参数。
是一个 use a 关系! [现实例子]比如说你要去拧螺丝,你是不是要借助 (也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作[UML 表现](图 1.2)有时在uml 图中不出现箭头只是虚线图1.2 Person 类与Screwdriver 类的依赖关系 理解:指Person 类可能要用到 Screwdriver 的一些方法,也可以这样说,要完成 Person 里的所有功 能,一定要有 Screwdriver 的方法协助才行。
Person 依赖于Screwdriver 的定义。
面向对象程序设计试题及答案一、试题1. 请简要解释面向对象(Object-Oriented)程序设计的概念。
2. 列举面向对象程序设计中的四个基本特征,并分别进行简要描述。
3. 请说明封装(Encapsulation)在面向对象程序设计中的作用和优势。
4. 解释继承(Inheritance)在面向对象程序设计中的概念和用途。
5. 什么是多态(Polymorphism)?请解释多态的概念以及其在面向对象程序设计中的重要性。
6. 简要介绍抽象类(Abstract Class)和接口(Interface)的概念,并说明它们之间的区别。
7. 请解释类(Class)与对象(Object)之间的关系。
8. 在面向对象程序设计中,什么是构造函数(Constructor)?请说明构造函数的作用和使用方法。
9. 请示范一个使用面向对象程序设计的简单实例,并说明你所设计的类的结构和功能。
二、答案1. 面向对象程序设计是一种以对象为中心的编程方法,通过定义表示对象属性和行为的类来组织程序结构,以实现代码的重用性、灵活性和可维护性。
2. (1)封装:将数据和对数据的操作封装在一个类中,通过访问权限控制,保护数据的安全性和完整性。
(2)继承:通过建立类之间的继承关系,实现代码的重用,具有层次性和扩展性。
(3)多态:允许不同类的对象对同一消息作出不同的响应,实现代码的灵活性和扩展性。
(4)抽象:通过抽象类和接口的定义,隐藏对象的具体实现细节,提供统一的接口和规范。
3. 封装的作用是将数据和对数据的操作封装在一个类中,外部无法直接访问类的内部实现细节,只能通过类提供的接口访问和操作数据。
封装的优势包括:(1)提高代码的可维护性和可读性,减少代码的重复。
(2)保护数据的安全性和完整性,防止外部直接对数据进行非法操作。
(3)降低模块之间的耦合度,提高代码的灵活性。
4. 继承是面向对象程序设计中的一个重要概念,它通过建立类与类之间的继承关系,实现代码的重用和扩展。
类与对象实验报告类与对象实验报告引言在计算机科学领域,类与对象是面向对象编程的基本概念之一。
通过定义类,我们可以创建对象,从而实现对数据和行为的封装和抽象。
本实验旨在通过实际操作,深入理解类与对象的概念,并掌握其在程序设计中的应用。
实验目的1. 理解类与对象的概念和关系;2. 学会使用类和对象进行数据封装和行为抽象;3. 掌握类与对象在程序设计中的应用。
实验过程1. 类的定义在本实验中,我们以一个简单的学生类为例进行说明。
首先,我们需要定义一个类来表示学生。
在类的定义中,我们可以包含学生的属性和行为。
比如,学生的姓名、年龄、性别等属性,以及学生的学习、休息等行为。
2. 对象的创建在类的定义完成后,我们可以通过创建对象来实例化这个类。
对象是类的具体实例,每个对象都有自己的属性和行为。
比如,我们可以创建一个名为"张三"的学生对象,给该对象的属性赋值,并调用对象的方法来执行相应的行为。
3. 属性的访问和修改通过对象,我们可以访问和修改类中定义的属性。
比如,我们可以通过对象的属性来获取学生的姓名和年龄,并通过修改属性的值来更新学生的信息。
4. 方法的调用类中的方法是对行为的抽象,通过方法,我们可以对对象进行操作。
比如,我们可以调用学生对象的学习方法,来模拟学生的学习行为。
同时,方法也可以接受参数,以实现更加灵活的功能。
实验结果通过实验,我们成功创建了一个学生类,并实例化了一个学生对象。
通过对象的属性和方法,我们可以获取和修改学生的信息,同时也可以模拟学生的行为。
这样,我们就实现了对学生的封装和抽象,提高了程序的可读性和可维护性。
实验总结通过本次实验,我深刻理解了类与对象的概念和关系。
类是对一类具有相同属性和行为的对象的抽象,而对象则是类的具体实例。
通过定义类和创建对象,我们可以实现对数据和行为的封装和抽象,提高了程序的可读性和可维护性。
在实际的程序设计中,类与对象是非常重要的概念,对于理解和应用面向对象编程具有重要意义。
客观世界是由对象组成,任何客观实体都是对象,复杂对象可以由简单对象组成。
具有相同属性和操作的对象可归纳成类,对象是类的一个实例。
类可以派生出子类,子类除了继承父类的全部特性外还可以有自己的特性。
对象之间的联系通过消息传递来维系。
封装是面向对象方法的一个重要原则,封装有两个含义:结合性即将属性和方法结合;信息隐蔽性利用接口机制隐蔽内部细节。
继承性是指子类可以自动拥有父类的全部属性与操作的机制。
继承可分为单重继承和多重继承两类。
继承简化了对现实世界的描述定义子类时不必定义那些在父类中已经定义过的属性和操作使软件的复用性提高。
多态性是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
2 什么是分解、耦合度和内聚度?耦合度是从模块外部考察模块的独立性程度。
模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。
模块间耦合高低取决于模块接口的复杂性、调用的方式及传递的消息。
内聚度(Cohesion)是模块内部各成份(语句或语句段)之间的联系。
模块内部各成份联系越紧,即其内聚度越大,模块独立性就越强。
分解:将系统分为更小成分3 什么是动态绑定?动态绑定,是指在程序运行时才将消息所请求的操作与实现该操作的方法进行连接。
4 什么是用例图,用例图有哪些部分组成。
用例是从用户的观点对系统行为的一个描述,特定的环璄下,特定的目标相关的系统与用户之间的一组可能的交互序列组成.用例图显示谁将是相关的用户、用户希望系统提供什么服务以及用户需要为系统提供的服务。
用例图包含6个元素:参与者(Actor)、用例(Use Case)、关联关系(Association)包含关系(Include)、扩展关系(Extend)、泛化关系(Generalization)5 用例图中参与者之间的关系有哪些?用例之间的关系有哪些?参与者之间的关系:泛化关系用例之间的关系:关联关系、包含关系、扩展关系、泛化关系地位:用例图显示了用例和活动者之间、用例之间、以及活动者之间的关系,这种关系描述了模型元素之间的语义联系。
类与类之间的关系对于理解面向对象具有很重要的作用,以前在面试的时候也经常被问到这个问题,在这里我就介绍一下。
类与类之间存在以下关系:
(1)泛化(Generalization)
(2)关联(Association)
(3)依赖(Dependency)
(4)聚合(Aggregation)
UML图与应用代码例子:
1.泛化(Generalization)
[泛化]
表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。
一般化的关系是从子类指向父类的,与继承或实现的方法相反。
[具体表现]
父类父类实例=new 子类()
[UML图](图1.1)
图1.1Animal类与Tiger类,Dog类的依赖关系
[代码表现]
1.class Animal{}
2.class Tiger extends Animal{}
3.public class Test
4.{
5.public void test()
6.{
7.Animal a=new Tiger();
8.}
9.}
2.依赖(Dependency)
[依赖]
对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。
[具体表现]
依赖关系表现在局部变量,方法的参数,以及对静态方法的调用
[现实例子]
比如说你要去拧螺丝,你是不是要借助(也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作
[UML表现](图1.2)
图1.2 Person类与Screwdriver类的依赖关系
1. public class Person{
2. /** 拧螺丝 */
3. public void screw(Screwdriver screwdriver){
4. screwdriver.screw();
5. }
6. }
3.关联(Association)
[关联]
对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。
[具体表现]
关联关系是使用实例变量来实现
[现实例子]
比如客户和订单,每个订单对应特定的客户,每个客户对应一些特定的订单;再例如公司和员工,每个公司对应一些特定的员工,每个员工对应一特定的公司
[UML图] (图1.3)
图1.3 公司和员工的关联关系
[代码表现]
∙public class Company{
∙ private Employee employee;
∙ public Employee getEmployee(){
∙ return employee;
∙ }
∙ public void setEmployee(Employee employee){
∙ this.employee=employee;
∙ }
∙ //公司运作
∙ public void run(){
∙ employee.startWorking();
∙ }
∙}
(4)聚合(Aggregation)
[聚合]
当对象A被加入到对象B中,成为对象B的组成部分时,对象B和对象A之间为聚集关系。
聚合是关联关系的一种,是较强的关联关系,强调的是整体与部分之间的关系。
[具体表现]
与关联关系一样,聚合关系也是通过实例变量来实现这样关系的。
关联关系和聚合关系来语法上是没办法区分的,从语义上才能更好的区分两者的区别。
[关联与聚合的区别]
(1)关联关系所涉及的两个对象是处在同一个层次上的。
比如人和自行车就是一种关联关系,而不是聚合关系,因为人不是由自行车组成的。
聚合关系涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。
比如电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
(2) 对于具有聚集关系(尤其是强聚集关系)的两个对象,整体对象会制约它的组成对象的生命周期。
部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失,部分也就随之消失。
比如张三的电脑被偷了,那么电脑的所有组件也不存在了,除非张三事先把一些电脑的组件(比如硬盘和内存)拆了下来。
[UML图](图1.4)
图1.3 电脑和组件的聚合关系
[代码表现]
∙public class Computer{
∙ private CPU cpu;
∙ public CPU getCPU(){
∙ return cpu;
∙ }
∙ public void setCPU(CPU cpu){
∙ this.cpu=cpu;
∙ }
∙ //开启电脑
∙ public void start(){
∙ //cpu运作
∙ cpu.run();
∙ }
∙}
聚合
聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a
的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
组合
组合也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
对于继承、实现这两种关系没多少疑问,他们体现的是一种类与类、或者类与接口间的纵向关系;其他的四者关系则体现的是类与类、或者类与接口间的引用、横向关系,是比较难区分的,有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖;
1.UML类图图示样例
2.1继承关系:
用空心三角形+实线来表示
2.2实现接口:
用空心三角形+虚线来表示
说明:以上为一对,两者都用空心三角形,继承关系比实现接口关系耦合性强,所以继承用实线,实现接口用虚线
2.3合成关系:
(Composition,也有翻译成‘组合、复合’的)是一种强的‘拥有’关系:
体现了严格的部分和整体的关系,部分和整体的生命周期一样。
在这里鸟和其翅膀就是合成(组合)关系,因为它们是部分和整体的关系,并且翅膀和鸟的生命周期是相同的。
合成关系用实心的菱形+实线箭头来表示。
另外,你会注意到合成关系的连线两端还有一个数字‘1’和数字‘2’,这被称为基数。
表明这一端的类可以有几个实例,很显然,一个鸟应该有两只翅膀。
如果一个类可能有无数个实例,则就用‘n’来表示
2.4聚合关系:
表示一种弱的‘拥有’关系
体现的是A对象可以包含B对象,但B对象不是A对象的一部分。
聚合关系用空心的菱形+实线箭头来表示
说明:以上为一对,可以这样记忆,复合关系比聚合关系耦合性强,所以复合菱形为实心,聚合菱形为空心
2.5关联关系:
用实线箭头来表示:
企鹅需要‘知道’气候的变化,需要‘了解’气候规律
2.6依赖关系(Dependency):
用虚线箭头来表示,动物依赖于氧气和水
说明:以上为一对,可以这样记忆,关联关系比依赖关系耦合性强,所以,关联关系用实线,依赖关系用虚线
2.7接口的两种表示方法:‘飞翔’,它表示一个接口图,与类图的区别主要是顶端有<<interface>>显示。
第一行是接口名称,第二行是接口方法。
接口还有另一种表示方法,俗称棒棒糖表示法,就是唐老鸭类实现了‘讲人话’的接口
2.8注释表示方法:。