1.91k likes | 2.06k Views
版权所有,复制必究. 面向对象技术. 北京工业大学计算机学院 软件学科部廖湖声主讲 liaohs@bjpu.edu.cn http://202 .112.73.60/ 网上教学. 计算机科学与技术的课程体系. 计算机软件与理论 计 算 机 软 件 计算机理论(离散数学、计算理论) 计算机体系结构 计算机体系结构、数字逻辑、计算机原理 计算机应用 计算机网络与通信、控制与接口、信息安全 人工智能、图形学、图像处理、多媒体技术. 软件课程体系与知识结构(1/3). 1、算法与数据结构 A. 数据结构 B. 算法分析与设计、并行计算 2、操作系统
E N D
版权所有,复制必究 面向对象技术 北京工业大学计算机学院 软件学科部廖湖声主讲 liaohs@bjpu.edu.cn http://202.112.73.60/网上教学
计算机科学与技术的课程体系 • 计算机软件与理论 • 计 算 机 软 件 • 计算机理论(离散数学、计算理论) • 计算机体系结构 • 计算机体系结构、数字逻辑、计算机原理 • 计算机应用 • 计算机网络与通信、控制与接口、信息安全 • 人工智能、图形学、图像处理、多媒体技术
软件课程体系与知识结构(1/3) • 1、算法与数据结构 • A. 数据结构 • B. 算法分析与设计、并行计算 • 2、操作系统 • A. 操作系统 • B. 分布式系统、分布式对象技术
软件课程体系与知识结构(2/3) • 3、编译与计算机语言 • 编译原理、计算机语言的设计与实现 • 形式语言与自动机、形式语义学 • 4、数据库技术 • 数据库系统原理 • 数据仓库、决策支持系统
软件课程体系和知识结构(3/3) • 5、软件工程 • 软件工程 • 软件项目管理、软件质量管理、软件环境与工具 • 6、软件方法学 • 面向对象方法、结构化方法 • 软件复用技术、软件体系结构
工作方法:科学研究和专门技术 • 信息资料检索 • 研究发展状况、技术发展状况 • 工程开发 • 可行性分析、需求分析、系统设计与测试 • 系统的技术总结==》技术报告 • 科学研究 • 问题分析与建模、提出解决方案、实验验证 • 解决方法的论证==》学术论文
引论:面向对象方法 • OO方法 • 分析问题和解决问题的方法 • 出发点: • 模仿人类认识世界的方法 • 基本方法: • 1、将客观世界的任何事物看作对象 Object • 2、进而分析事物的组成关系和交互关系 • 3、建立描述客观世界的抽象模型
面向对象方法的应用 • 1、程序设计 OOP:以程序模块为 Object • 2、系统分析 OOA:以领域事物为 Object • 3、系统设计 OOD:以系统组成元素为 Object • 4、软件工程 OOSE:综合OOP、OOA和OOD • 5、数据模型 OODB:以数据为 Object
参考资料 • 蒋惠等,时代新潮流 UML 设计核心技术,北京希望出版社 • 李英军等译,设计模式,机械工业出版社 • 刘润东,UML 对象设计与编程,北京希望出版社 • 刘宗田等译,C++ 编程思想,机械工业出版社 • 黄理,用 JSP 轻松开发 Web 网站,北京希望出版社 • 面向对象技术网站大全,www.cetus-links.org
第一部分 面向对象程序设计 • 1、OOP 的基本概念 • 2、对象关联 • 3、对象建模初步 • 4、多态性及其应用 • 5、可复用软件设计 • 6、活用 C++ 语言
第一讲 OOP 的基本概念 • OOP 是将 OO 方法应用于程序设计 • 是一种模块化程序设计 • 对象是一种程序模块 • 程序由多个对象组成 • OOP 的实现需要 OOPL • 面向对象程序设计语言 • Smalltalk、C++、Java
1.1 OOP 的由来 • 传统程序设计 • 数据结构 + 算法 = 程序 • 模块程序设计 • 数据结构 + 相关算法 = 程序模块 • 程序模块 + 交互会话 = 程序 • OOP • 对象 + 消息传递 = 程序
模块化程序设计 • 基本概念 • 以数据结构为中心,集中相关的算法实现过程,形成相对独立的模块。 • 按照信息隐蔽的原则,形成实现细节的局部化。 • 例:数据文件处理模块 • 以文件句柄、缓冲区为中心,集中相关过程 • 隐蔽数据结构和实现算法细节
主要特征 • 传统的问题求解 • 设计数据结构 • 通过功能分解来实现算法(逐步求精) • 模块化程序设计的问题求解 • 基于数据和功能的模块划分 • 每个模块包含有私有数据和一组过程 • 避免了全局数据的共享
什么是对象 • 一种抽象描述 = 特性+行为 • 描述客观世界中相对独立的事物或实体
程序中的对象 • 例:C语言的文件 • FILE *fp = fopen(name, "w"); • ... putc(‘a’, fp) ... • ... fprintf(fp, ...) • fclose(fp); • 对象的封装性 • 完备的文件处理函数隐蔽了文件实现细节
OOP中的对象 • 代表程序模块 • 有标识 如:fp • 有属性 如:FILE的成员 • 有操作 如:fopen等函数 • 封装性 属性不对外公开 • 对象的说明和引用 • 类似于结构变量
1.2 抽象数据类型Abstract Data Type 对象设计与分类描述的方法 • 抽象描述模块数据和操作,支持具有相同数据结构和操作的软件模块(对象) • 提供足够的操作,封装内部状态和数据
ADT 的设计 • 抽象 abstract: • 分析客观世界的事物,提取反映事物性质的必要信息,构成模型。 • 事物性质: • 提取涉及的数据信息、确认需要的操作 • 例:对于职工的管理,提取管理相关的数据和操作,来定义系统中的职工
ADT的描述(对象类) • 抽象定义: • 通过定义属性数据、操作和约束条件,对客观问题进行形式化的描述说明 • ADT例: 学生ADT • 属性:学号、姓名、上课次数、考试成绩 • 操作:上课、做作业、上机、考试 • 约束条件:上课次数>10 可以参加考试
ADT的实现:学生类 • C++、Java等OOPL语言的支持 • Yes:属性、操作;No:约束条件 Student id 学号 name 姓名 passExam( int ) getScore : int
class Student { int id; int score; String name; Student( int id, String nam ) { this.id = id; // 初始化 name = nam; score = 0; } void passExam( int s ) { score = s; } int getScore( ) { return score; } }
对象的说明和引用 Student Li = new Student ( 970302, “Li Bing”); // 说明变量 Li:空间分配、初始化 Li.passExam( 92 ); int x = Li.getScore( ); // 操作该对象,调用成员函数 • 用法和结构变量基本相同
ADT 的作用 • 形成一种类型系统 • 对象类代表一种数据类型 • 可重复使用,扩充了编程语言 • 类型的含义 • 数据结构 + 可参加的运算(操作) • 所有运算均与运算数据的类型有关 • ADT :数据抽象 + 功能抽象 • 符合人们的认识问题的方法
1.3 实例分析:有理数类 • 数据需求:分子、分母; • 操作需求:构造、四则运算、输出 Ration nume 分子 deno 分母 Print( ) Mul( Ration ) : Ration ……
import java.io.*; class Ration { int nume, deno; // 属性:分子和分母 Ration( int n, int d ) { nume = n; deno = d; // 构造 } void Print( ) { System.out.print( nume + "/" + deno ); } // 输出 Ration Mul( Ration x ) { return new Ration( nume * x.nume , deno * x.deno ); } // 乘法 }
测试程序 public class Test { public static void main( String[] args ) { Ration r1 = new Ration (5, 12); Ration r2 = new Ration (3, 11); Ration r = r1.Mul( r2 ); r.Print( ); } }
1.4 消息传递初步 • 消息传递:控制手段 • 向对象发消息:激活操作 • 消息 = 消息名(参数) • Java的支持 • 对象名.方法名(参数) • 如:r1.Mul( r2 ) • OOP • 对象 + 消息传递 = 运行中的程序
上例中的消息传递 主程序 2. Ration( 3, 11 ) 1. Ration( 5, 12 ) 3. Mul ( r2 ) 5. Print 有理数1 r1 计算结果 r 有理数2 r2 4. Ration( n, d )
1.5 基于类的软件模块化 • 模块的设计、使用与实现的分离 • 设计者———类的外部设计 • 使用者———操作的功能与调用方法 • 实现者———数据结构和实现算法 • 模块的接口 • 类成员函数的功能设计和函数原型
例:C 语言字符串处理的封装 隐蔽字符串存储结构、空间分配的细节 • class String { char *buf; // 首地址 public: String( char *s ); ~String( ) { delete buf; } // 释放 char *getString( ) { return buf; } void strcat( char *s ); // 字符串连接 int strcmp( char * s ) { // 字符串比较 return strcmp( buf, s ); } };
String 类的实现 • String::String( char *s ) { buf = new char [ strlen(s)+1 ]; // 空间分配 strcpy( buf, s ); // 字符串构造(复制) } • void String::strcat( char *s ) { char *p = new char [ strlen(buf)+strlen(s)+1 ]; strcat( strcpy( p, buf ), s ); // 分配空间、复制 delete buf; // 释放原空间 buf = p; } // 字符串连接
习题: • 1、扩充上述有理数的类定义和计算程序,补充加法、减法、除法的功能。 • 2、扩充上述字符串的类定义,补充两个成员函数,分别完成 1)将给定的整数变换为字符串 itoa( int n ) 和 2)检查该字符串str1中是否存在指定的字符子串 strstr(str) ;并编制一个计算程序,测试该类的所有功能
第二讲 对象关联 两种对象组成关系 • 整体与部分关系 • 例:硬盘是计算机的组成部分 • 例:报表输出是管理信息系统的组成部分 • 一般与特殊关系 • 例:研究生是一种学生 • 例:汽车是一种交通工具
2.1 整体部分关系 • 部分对象作为整体对象的数据成员 例 2-1:由多个结点组成的链表 • C语言的实现 设置结点结构,以首结点指针标识链表。 • OOPL 的实现 提供 List 类,封装相关处理 隐蔽内部结构和实现算法 为使用者提供完整的操作
链表的实现 import java.util.*; class Node { // 链表结点类 Object elem; Node next; // 元素和下一结点 Node( Object e, Node n ) { elem = e; next = n; } }
public class List { Node head, tail; // 表头、表尾指针 List( ) { head = tail = null; } int getCount( ) { // 获得元素个数 int n = 0; for( Node p = head; p != null; p = p.next ) n++; return n; } void addHead( Object e ) { // 添加头元素 Node p = new Node ( e, head ); if( head == null ) tail = p; head = p; }
void addTail( Object e ) { // 添加尾元素 Node p = new Node ( e, null ); if( tail != null ) tail.next = p; else head = p; tail = p; } Object removeHead( ) { // 删除头元素 if( head == null ) return null; Object x = head; head = head.next; if( x == tail ) tail = null; return x; } Object fetch( int i ) { // 取指定元素 for( Node p = head; p != null; p = p.next ) if( i-- == 0 ) return p.elem; return null; } }
实现技巧 • 部分对象 • 其引用(指针)作为数据成员 • 链表成员函数 • 完备性(封装内部实现) • 效率和可读性 • 开放对象封装 • 元素类型 • Object 适用各种元素
2.2 一般与特殊关系 • 客观世界存在的一般特殊关系: • 学生是人,职工是人,继承人的属性和行为 • 继承属性和行为: • 姓名、年龄、走路、说话 • 特殊属性和行为: • 学生:学号、上学;职工:工作单位、上班 • 多重继承关系: • 在职研究生是学生,又是职工
继承的实现 • OOPL 的支持 • 说明派生类继承基类的属性和方法,如: • class 派生类 extends 基类 { • // 仅描述特殊的属性和方法 • } // 复用基类的数据结构和方法
例2-3:由链表类派生字符串表 • 字符串链表是一种链表 public class StringList extends List { public StringList( ) { super( ); } boolean is_present( String s ) { // s 存在否 ? for( int i=0; i < getCount( ); i++ ) if( s.equals( fetch( i ) ) ) return true; return false; } } • 复用 List 类的数据结构与部分接口
List head: Node tail: Node getCount( ): int addHead(Object) addTail(Object) removeHead():Object fetch(int):Object StringList String is_present( ) : boolean 对象关联的图示
对象属性设计与对象关联 • 设计原则 • 独立性:自身的属性、状态 • 设计例: class Person 人的信息 { 姓名; 正确 性别; 正确 出生年月; 正确 履历; 错误(类型层次) 教龄; 错误(部分实例具备) 拥有的自行车数量; 错误(领域专用) } • 上述错误应采用对象关联解决
应用例: • 要求:输入一组英语单词,删除重复出现的单词后,输出到屏幕。 • 数据结构: • 单词表:保存已输出的单词 • 算法: • 1、从命令行取一个单词 • 2、检查是否存在于单词表 • 3、如果不存在,则存入单词表,并输出 • 4、重复以上过程
主程序的实现 import java.io.*; public class Test { public static void main( String[] args ) { StringList words = new StringList( ); for( int i=0; i < args.length; i++ ) { if ( words.is_present( args[i] ) ) continue; words.AddTail( args[i] ); System.out.println( args[i] ); } } }
2.3 从基类到软件复用 • 基类的设置 • 公共属性与方法,形成软件复用的基础 • 可重用基类的设计 • 独立性、完备性、可靠性、接口友好 • 可利用的基本类库 • 如:Microsoft Foundation Class • 如:Java Foundation Class
MFC的通用类 • 公共基类 CObject • 提供持久性、诊断等通用功能 • 字符串类 CString • 封装字符串处理 • 双向链表类 CObList…… • 元素的增删改、枚举、查找 • 动态数组类 CObArray…… • 按索引的元素存取、增删改 • 散列表 CMapStringToOb • 查找、枚举、赋值
Java 常用基本类 • 向量类 Vector • 基于索引的元素访问、容量扩充 • 枚举控制类 Enumeration • 枚举各种容器的元素(包括:输入流、向量) • 散列表类 Hashtable • 基于关键字的元素访问 • 文件读取类 FileReader • 字符流的输入 • 格式化输出类 PrintWriter • 基本类型数据的输出
例 2-4:数据库查询结果集的设计 • 需求: • 由多个记录组成,可顺序查找 • 每个记录由多个字段组成 • 可根据字段名、或字段序号查找字段数据 • 提供可复用的模块 • 设计: • 提供依次枚举记录的手段 • 提供按照字段名、或序号查找字段数据的手段 • 提供构造记录,组织结果集的手段