1、从素数问题看面向对象
1.1 问题的提出
素数的定义
- 除了1与本身之外,不能被其他正整数整除的数,叫作素数,也叫质数
由定义判断素数
- 对于数 n ,从i=2,3,4,5…到 n-1 判断 n 能否被 i 整除,如果全部不能整除,则 n 是素数,只要有一个能除尽,则 n 不是素数,为了压缩循环次数,可将判断范围从 2 ~ n-1 改为 2 ~ sqrt(n)
筛选法求素数序列
1.2 传统的结构化方法解决方案
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int * sieve,n;
int iCounter= 2,iMax,i;
printf( "Please input max number: ");
scanf("%d",&n);
sieve = (int *) malloc((n-1) * sizeof( int));
for(i=0;i<n-1;i++) { sieve[i]=i+2; }
iMax = sqrt(n);
while (iCounter<= iMax){
for (i = 2*iCounter-2;i<n-1; i+= iCounter)
sieve[i]=0;
iCounter++;
}
for(i=0;i<n-1;i++)
if (sieve[i]!=0)
printf("%d ",sieve[i]);
return 0;
}
流程图
1.3 面向对象的解决方案
import java.lang.Math;
public class Test{
public static void main(String args[]) {
int n=50;
int sieve[]=new int[n-1];
int iCounter=2, iMax, i;
for(i=0;i<n-1;i++) {sieve[i]=i+2;}
iMax=(int)Math.sqrt(n);
while(iCounter<=iMax){
for (i=2*iCounter-2; i<n-1; i+=iCounter)
sieve[i]=0;
iCounter++;
}
for(i=0; i<n-1; i++)
if (sieve[i]!=0) System.out.println(sieve[i]);
}
}
上述程序是使用Java语言实现但是并不是对象思维。
用对象思维解决问题
筛选法求素数的类图
面向对象的编程(C++语法实现)
-
基类
class Item{ public: Item* source; Item (Item* src) {source=src;} virtual int out() {return 0;} };
-
计数器
class Counter: public Item{ int value; public: int out() {return value++;} Counter(int v):Item(0){value=v;} };
-
过滤器
class Filter:public Item{ int factor; public: int out(){ while(1){ int n=source->out(); if (n%factor) return n; } } Filter(Item *src, int f):Item(src) {factor=f;} };
-
筛子
class Sieve: public Item{ public: int out(){ int n=source->out(); source= new Filter(source, n); return n; } Sieve(Item *src):Item(src){} };
-
主函数
void main(){ Counter c(2); Sieve s(&c); int next, n; cin>>n; while(1){ next=s.out(); if(next>n) break; cout<<next<<" "; } cout<<endl; }
课程三大目标
OO:建立对象的思维方式,对面向对象思想和理论有进一步的理解
UML:能够熟练地使用UML表达面向对象的设计思想
Model:运用对象技术的一般原则和模式进行应用系统的分析和设计建模
三大目标之间的关系
Model:建模是最终目的
OO:面向对象技术是一种建模理论
UML:统一建模语言是一种体现OO的建模语言,是将OO理论转化为实践的工具
2、 面向对象技术基础
面向对象技术是一系列指导软件构造的原则(如抽象、封装、多态等),并通过语言、数据库和其它工具来支持这些原则
从本质上讲,对象技术对一系列相关原则的应用
面向对象技术 = 类+对象+抽象+封装+继承+多态+消息…
2.1 面向对象技术的发展历史
2.2 面向对象技术的优势
- 沟通——在计算机中模拟现实世界的事和物
- 顺应人类思维习惯,让软件开发人员在解空间中直接模拟问题空间中的对象及其行为
例子:“东北一家人“
- 稳定——较小的需求变化不会导致系统的结构大的改变
- 复用——提高质量,降低成本
- 代码重用:类库、框架等重用机制
- 能提高质量,减少由于编制新的系统代码而产生的成本
- 通过继承、关联、封装等手段
3、对象和类
面向对象技术是由一系列的概念和原则组成的,而这些概念和原则中的两个最基础﹑最重要的就是对象和类。
3.1 对象
对象是一个实体,这个实体:
- 具有明确定义的边界和标识
- 边界意味着对象是一个封装体,通过封装来与其它对象分隔
- 标识则表明每一个对象都是唯一的
- 对象封装了状态和行为
- 对象的状态通过对象的属性(attribute)和关系(relationship)来表达
- 对象的行为通过对象的操作(operation)、方法(method)和状态机(state machine)来表达
在UML中,对象用矩形框来表示,对象的名字写在矩形框内部,并加上下划线来表示
3.2 类
- 类就是一系列对象的抽象描述,这些对象共享相同的属性、操作、关系和语义
- 一个具体的对象是该类的一个实例
- 类是一种抽象
- 将相似的实体抽象成相同的概念
- 抽象过程强调相关特征而忽略其它的特征
在UML中,采用矩形框表示类,可以将矩形框划分为三个区域,分别表示类名、属性和操作
属性
- 属性(attribute)是类的特征或特性
- 属性的值是某一特定对象的属性值
- 在类中属性名必须是唯一的
- 每一个类的实例都有为这个类定义的所有属性的值
操作
- 操作(operation)访问或修改对象的属性值
- 对象的行为是由为此对象定义的一系列操作决定的
- 一个类可能同时存在多个实例,也可能在某一时刻没有实例
- 一个类的所有实例都可以使用在这个类中定义的操作
4、面向对象技术相关原则
4.1 抽象-Abstraction
- 抽象是揭示事物区别于其他事物的本质特征的过程
- 是一个分析和理解问题的过程
- 抽象的结果取决于使用者的目的,应该包括使用者所感兴趣的那些职责,而忽略掉其它不相关的部分
- 对象到类的过程就是抽象
- 即将所见到的具体实体抽象成概念,从而在计算机世界中进行描述和各种操作
4.2 封装 - Encapsulation
- 封装是对客户(使用者)隐藏具体实现细节
- 客户只依赖于接口
- 通过封装实现信息隐藏和数据抽象
为什么要封装
数据一致性
在面向对象中类成员经常是私有的,我们只能通过接口访问数据。
class ShippingAddress {
private long cityCode;
private string address;
public long ModifyAddress(String address)
}
可见性问题
4.3 分解 - Decomposition
- 分解是指将单个大规模复杂系统划分为多个不同的小构件
- 分解的构件通过抽象、封装等技术形成相对独立的单元,可以独立设计和开发,从而实现化繁为简、分而治之
- 分解的方法
- 结构化方法:函数、模块进行功能分解
- 面向对象:基于类和对象的分解基础上,进行合理的打包和分层,从而形成更加复杂的分解结构
4.4 泛化 - Generalization
- 是类之间的一种“是”(is a/ is kind of)关系,通过该关系一个类(子类)可以共享另外一个或多个类(父类)的结构和行为
- 采用继承(Inheritance)实现泛化关系
- 通过泛化关系,可以建立类之间的层次结构,根据继承层次中父类的个数不同,分为:
- 单一继承
- 多重继承
一般我们称父类是子类的泛化,子类继承父类
单一继承
多重继承
Use multiple inheritance only when needed and always with caution!
继承
- 子类继承父类所有的内容:属性、操作、关系和语义
- 其访问权限仍受可见性的约束
- 子类还可以:
- 添加新的属性、操作、关系和语义
- 重定义继承的操作
- 设计继承层次
- 父类定义公共的属性、操作、关系和语义
- 针对不同的情况定义不同的子类,以扩展父类的属性、操作、行为和语义
4.5 多态 - Polymorphism
- 多态是在统一外表(接口)下隐藏不同实现的能力
- 即一个接口可以有不同的实现行为
- 是面向对象技术的本质特征
应用多态性
- 假设我们有一个数组sharr,里面放着一排Shape,但是不知道哪些是Rectangle,哪些是Circle。利用多态性,我们可以:
for (int i = 0; i < sharr.length; ++i) {
Shape shape = (Shape)sharr[i];
shape.draw();
}
- 遍历整个数组的过程中,各个Shape自己知道应当如何在画布上绘制自己。shape.draw()这同一行代码在shape指向不同的对象时表现出不同的行为,这就是所谓多态性
4.6 分层 - Hierarchy
- 分层是指面向不同的目标建立不同的抽象级别层次,从而在不同的抽象层次对系统进行分解,进一步简化对系统的理解
- 两种分层结构
- 类层次结构:在不同的抽象级别进行对象的抽象,通过泛化关系,行程类间的继承层次结构
- 对象层次结构:是指对象间的组成结构,即大的对象由小的对象组成
4.7 复用 - Reuse
- 复用是借助于已有软件的各种有关知识建立新的软件的过程
- 将软件看成是由不同功能部分的构件所组成的有机体,每个构件在设计编写时可以被设计成完成同类工作的通用工具
- 如果完成各种工作的构件被建立起来以后,编写特定软件的工作就变成了将各种不同构件进行组合的简单问题,从而对软件产品的最终质量和维护工作都有本质性的改变
应用复用原则
- 系统开发各个阶段都可能涉及到复用
- 从最底层的代码复用,到设计复用、架构复用,再到需求复用,甚至于延伸到特定业务领域的复用
- 复用原则要求设计者不仅针对当前的业务需求开展设计,还需要考虑业务的通用性和可扩展性等问题,从而设计抽象层次高、复用粒度大的组件
5、建立面向对象思维
5.1 案例
我的以为朋友结婚了
A. 这里面有什么事物?
月老,小伙,姑娘,恋人,玫瑰花
B. 每个事物看上去是什么样的?
月老,看上去有些年纪了,挺热心的
小伙,看上去很强壮,很诚实的
姑娘,看上去好漂亮,还很温柔
恋人,看上去很黏糊,当然就结婚了
玫瑰花,火红火红的,难怪姑娘动情了
C. 每个事物能做点什么用?
月老:牵线搭桥,介绍认识
小伙:追求献花,表达爱意
姑娘:仰慕倾情,以身相许
恋人:拍拖,…,结婚
玫瑰花:令姑娘头晕,传情示爱
D. 这些事物都呆在什么地方?
月老:婚介所,交友网站
小伙:软件园,住回龙观
姑娘:人民医院,住望京
恋人:情侣路,电影院, …
玫瑰花:花店里,小伙手中,姑娘手中
E. 这些事物之间有什么关系?
F. 这些事物是怎么成事的?
月老牵线搭桥,介绍小伙和姑娘认识
姑娘和小伙一见钟情,成为一对恋人
一对恋人开始拍拖
小伙追求献花,表达对姑娘的爱意
姑娘收到999火红玫瑰,激动得头晕目眩
小伙真心求婚,姑娘以身相许
一对恋人终于走入婚姻殿堂
5.2 用面向对象思维分析案例
A.这里面有什么事物?
类和对象
对象->类
我 — 本剧与我无关
我的朋友 小伙
我朋友的妻子 姑娘
月老
恋人
玫瑰
B.每个事物看上去是什么样的?
类的属性
每个事物看上去都有自己的属性,在每个属性上都有一个特征值(对象的属性)
小伙:体格,特征值:强壮
姑娘:性情,特征值:温柔
月老:年纪,特征值:较大
恋人:关系,特征值:黏糊
玫瑰花:颜色,特征值:火红
C.每个事物能做点什么用?
类的操作
每个事物都具备某种能力(对象的操作)
小伙:追求、送花、娶亲
姑娘:爱慕、相许、出嫁
月老:牵线搭桥
玫瑰:示爱
D.这些事物都呆在什么地方?
类的状态、部署
每个事物都会有它合理的或者必须的空间位置和逻辑位置。尤其当这些位置对事物的行为造成重要影响的时候,表明他们的位置极其重要
本剧列出的位置对故事主要情节没有太大的影响,系统中不予考虑
E.这些事物之间有什么关系?
类之间间的关联
事物之间的关系非常多,面向对象的观点一般分为主要的三类(关系):
整体-部分关系(聚合和组合),甲是乙的一个组成部分:如恋人和小伙,恋人和姑娘的关系
抽象-具体关系(泛化),甲是乙的一个特例:如人和小伙,人和月老,人和姑娘的关系
协作关系(关联),甲会对乙做点什么:如月老和小伙、姑娘,小伙和玫瑰,小伙和姑娘的关系
F.这些事物是怎么成事的?
类之间的交互(用例实现)
每个事物都会尽量利用伙伴的能力
整体事物的能力依靠部分事物的能力
抽象事物的属性和能力就是具体事物的属性和能力;具体事物除了有抽象事物的属性和能力外,还可以有自己特殊的
事物分工协作,互通信息,共同完成整体的目标
面向对象的分析和设计的核心
俗语和术语之间的对应
5.3 利用UML表达分析结果
反应结婚过程的静态类图
反应结婚过程的活动图
搞清过程
初次见面的顺序图
复述情节
初次见面的通信图
理清头绪
恋人关系发展的状态机图
定点观察