1、从素数问题看面向对象

1.1 问题的提出

素数的定义

  • 除了1与本身之外,不能被其他正整数整除的数,叫作素数,也叫质数

由定义判断素数

  • 对于数 n ,从i=2,3,4,5…到 n-1 判断 n 能否被 i 整除,如果全部不能整除,则 n 是素数,只要有一个能除尽,则 n 不是素数,为了压缩循环次数,可将判断范围从 2 ~ n-1 改为 2 ~ sqrt(n)

筛选法求素数序列

image-1673422871287

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;
}

流程图

image-1673776445954

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语言实现但是并不是对象思维。

用对象思维解决问题

image-1673777007243

筛选法求素数的类图

image-1673777000675

面向对象的编程(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 面向对象技术的发展历史

image-1673778531408

2.2 面向对象技术的优势

  • 沟通——在计算机中模拟现实世界的事和物
    • 顺应人类思维习惯,让软件开发人员在解空间中直接模拟问题空间中的对象及其行为

例子:“东北一家人“

image-1673779407257image-1673779494378

  • 稳定——较小的需求变化不会导致系统的结构大的改变

image-1673779679280

  • 复用——提高质量,降低成本
    • 代码重用:类库、框架等重用机制
    • 能提高质量,减少由于编制新的系统代码而产生的成本
    • 通过继承、关联、封装等手段

image-1673779864421

3、对象和类

​ 面向对象技术是由一系列的概念和原则组成的,而这些概念和原则中的两个最基础﹑最重要的就是对象和类。

3.1 对象

对象是一个实体,这个实体:

  • 具有明确定义的边界和标识
    • 边界意味着对象是一个封装体,通过封装来与其它对象分隔
    • 标识则表明每一个对象都是唯一的
  • 对象封装了状态和行为
    • 对象的状态通过对象的属性(attribute)和关系(relationship)来表达
    • 对象的行为通过对象的操作(operation)、方法(method)和状态机(state machine)来表达

在UML中,对象用矩形框来表示,对象的名字写在矩形框内部,并加上下划线来表示

image-1673780805584

3.2 类

  • 类就是一系列对象的抽象描述,这些对象共享相同的属性、操作、关系和语义
    • 一个具体的对象是该类的一个实例
  • 类是一种抽象
    • 将相似的实体抽象成相同的概念
    • 抽象过程强调相关特征而忽略其它的特征

在UML中,采用矩形框表示类,可以将矩形框划分为三个区域,分别表示类名、属性和操作

image-1673781109561

属性

  • 属性(attribute)是类的特征或特性
    • 属性的值是某一特定对象的属性值
    • 在类中属性名必须是唯一的
    • 每一个类的实例都有为这个类定义的所有属性的值

image-1673781253801

操作

  • 操作(operation)访问或修改对象的属性值
  • 对象的行为是由为此对象定义的一系列操作决定的
  • 一个类可能同时存在多个实例,也可能在某一时刻没有实例
  • 一个类的所有实例都可以使用在这个类中定义的操作

image-1673781428422

4、面向对象技术相关原则

4.1 抽象-Abstraction

  • 抽象是揭示事物区别于其他事物的本质特征的过程
    • 是一个分析和理解问题的过程
    • 抽象的结果取决于使用者的目的,应该包括使用者所感兴趣的那些职责,而忽略掉其它不相关的部分
  • 对象到类的过程就是抽象
    • 即将所见到的具体实体抽象成概念,从而在计算机世界中进行描述和各种操作

image-1673781933176

4.2 封装 - Encapsulation

  • 封装是对客户(使用者)隐藏具体实现细节
    • 客户只依赖于接口
    • 通过封装实现信息隐藏和数据抽象

为什么要封装

image-1673782099813

数据一致性

image-1673782233985

在面向对象中类成员经常是私有的,我们只能通过接口访问数据。

class ShippingAddress {
 private long cityCode;
 private string address;
 public long ModifyAddress(String address)
}

可见性问题image-1673782413197

4.3 分解 - Decomposition

  • 分解是指将单个大规模复杂系统划分为多个不同的小构件
    • 分解的构件通过抽象、封装等技术形成相对独立的单元,可以独立设计和开发,从而实现化繁为简、分而治之
  • 分解的方法
    • 结构化方法:函数、模块进行功能分解
    • 面向对象:基于类和对象的分解基础上,进行合理的打包和分层,从而形成更加复杂的分解结构

4.4 泛化 - Generalization

  • 是类之间的一种“是”(is a/ is kind of)关系,通过该关系一个类(子类)可以共享另外一个或多个类(父类)的结构和行为
    • 采用继承(Inheritance)实现泛化关系
  • 通过泛化关系,可以建立类之间的层次结构,根据继承层次中父类的个数不同,分为:
    • 单一继承
    • 多重继承

一般我们称父类是子类的泛化,子类继承父类

单一继承

image-1673782971757

多重继承

image-1673782983754

Use multiple inheritance only when needed and always with caution!

继承

  • 子类继承父类所有的内容:属性、操作、关系和语义
    • 其访问权限仍受可见性的约束
  • 子类还可以:
    • 添加新的属性、操作、关系和语义
    • 重定义继承的操作
  • 设计继承层次
    • 父类定义公共的属性、操作、关系和语义
    • 针对不同的情况定义不同的子类,以扩展父类的属性、操作、行为和语义

image-1673783311177

4.5 多态 - Polymorphism

  • 多态是在统一外表(接口)下隐藏不同实现的能力
    • 即一个接口可以有不同的实现行为
    • 是面向对象技术的本质特征

image-1673783416470

应用多态性

  • 假设我们有一个数组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

  • 分层是指面向不同的目标建立不同的抽象级别层次,从而在不同的抽象层次对系统进行分解,进一步简化对系统的理解
  • 两种分层结构
    • 类层次结构:在不同的抽象级别进行对象的抽象,通过泛化关系,行程类间的继承层次结构
    • 对象层次结构:是指对象间的组成结构,即大的对象由小的对象组成

image-1673789678199

4.7 复用 - Reuse

  • 复用是借助于已有软件的各种有关知识建立新的软件的过程
    • 将软件看成是由不同功能部分的构件所组成的有机体,每个构件在设计编写时可以被设计成完成同类工作的通用工具
    • 如果完成各种工作的构件被建立起来以后,编写特定软件的工作就变成了将各种不同构件进行组合的简单问题,从而对软件产品的最终质量和维护工作都有本质性的改变

应用复用原则

  • 系统开发各个阶段都可能涉及到复用
    • 从最底层的代码复用,到设计复用、架构复用,再到需求复用,甚至于延伸到特定业务领域的复用
  • 复用原则要求设计者不仅针对当前的业务需求开展设计,还需要考虑业务的通用性和可扩展性等问题,从而设计抽象层次高、复用粒度大的组件

5、建立面向对象思维

5.1 案例

我的以为朋友结婚了

A. 这里面有什么事物? 月老,小伙,姑娘,恋人,玫瑰花

B. 每个事物看上去是什么样的? 月老,看上去有些年纪了,挺热心的 小伙,看上去很强壮,很诚实的 姑娘,看上去好漂亮,还很温柔 恋人,看上去很黏糊,当然就结婚了 玫瑰花,火红火红的,难怪姑娘动情了

C. 每个事物能做点什么用? 月老:牵线搭桥,介绍认识 小伙:追求献花,表达爱意 姑娘:仰慕倾情,以身相许 恋人:拍拖,…,结婚 玫瑰花:令姑娘头晕,传情示爱

D. 这些事物都呆在什么地方? 月老:婚介所,交友网站 小伙:软件园,住回龙观 姑娘:人民医院,住望京 恋人:情侣路,电影院, … 玫瑰花:花店里,小伙手中,姑娘手中

E. 这些事物之间有什么关系?

image-1673790816518

F. 这些事物是怎么成事的? 月老牵线搭桥,介绍小伙和姑娘认识 姑娘和小伙一见钟情,成为一对恋人 一对恋人开始拍拖 小伙追求献花,表达对姑娘的爱意 姑娘收到999火红玫瑰,激动得头晕目眩 小伙真心求婚,姑娘以身相许 一对恋人终于走入婚姻殿堂

5.2 用面向对象思维分析案例

A.这里面有什么事物? 类和对象 对象->类 我 — 本剧与我无关 我的朋友 小伙 我朋友的妻子 姑娘 月老 恋人 玫瑰

B.每个事物看上去是什么样的? 类的属性 每个事物看上去都有自己的属性,在每个属性上都有一个特征值(对象的属性) 小伙:体格,特征值:强壮 姑娘:性情,特征值:温柔 月老:年纪,特征值:较大 恋人:关系,特征值:黏糊 玫瑰花:颜色,特征值:火红

C.每个事物能做点什么用? 类的操作 每个事物都具备某种能力(对象的操作) 小伙:追求、送花、娶亲 姑娘:爱慕、相许、出嫁 月老:牵线搭桥 玫瑰:示爱 D.这些事物都呆在什么地方? 类的状态、部署 每个事物都会有它合理的或者必须的空间位置和逻辑位置。尤其当这些位置对事物的行为造成重要影响的时候,表明他们的位置极其重要 本剧列出的位置对故事主要情节没有太大的影响,系统中不予考虑

E.这些事物之间有什么关系? 类之间间的关联 事物之间的关系非常多,面向对象的观点一般分为主要的三类(关系): 整体-部分关系(聚合和组合),甲是乙的一个组成部分:如恋人和小伙,恋人和姑娘的关系 抽象-具体关系(泛化),甲是乙的一个特例:如人和小伙,人和月老,人和姑娘的关系 协作关系(关联),甲会对乙做点什么:如月老和小伙、姑娘,小伙和玫瑰,小伙和姑娘的关系

F.这些事物是怎么成事的? 类之间的交互(用例实现) 每个事物都会尽量利用伙伴的能力 整体事物的能力依靠部分事物的能力 抽象事物的属性和能力就是具体事物的属性和能力;具体事物除了有抽象事物的属性和能力外,还可以有自己特殊的 事物分工协作,互通信息,共同完成整体的目标 面向对象的分析和设计的核心

俗语和术语之间的对应

image-1673791637451

5.3 利用UML表达分析结果

反应结婚过程的静态类图

image-1673791863325

反应结婚过程的活动图

搞清过程

image-1673791904000

初次见面的顺序图

复述情节

image-1673791942797

初次见面的通信图

理清头绪

image-1673792077923

恋人关系发展的状态机图

定点观察

image-1673792101018