《面向对象技术与方法》06、类与对象之一

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

符号常量 成员数据
依次为:static、非static。 再依次为:protected、friendly、private。 另一主张:将客户程序关心的(公有的)放在前面,而成员数据通常 不是公有的,故宜放后将其置于最后。 借鉴:Java API的源代码中两种写法都有,甚至有些类穿插出现。
• •
构造方法 成员方法
public class NameHiding { private double x = 0; public boolean set(double x) { if (x > 0) { this.x = x + get(); return true; } else return false; } public double get() { double y = x * x; double x = y + 1; return x; } } 因继承屏蔽名 因继承屏蔽名 字称为hiding 字称为hiding
抽象取决于观察者的角度
例子:城市地图是对城市的抽象;数字电路图是对线路板的抽象。 不同的抽象层次:军用地图比民用地图含有更丰富的信息。 不同的抽象角度:线路板有数字电路图与线路布局图。
6-5

抽象是人类长期认识世界与改造世界的结果
英国哲学家与数学家罗素在其名著《数理哲学导论》中断言:
发现一对鸡、两昼夜都是数2的实例,一定需要很多年代,其中 所包含的抽象程度确实不易达到。 至于1是一个数的发现,也必定很困难。 说到0,这更是晚近加入的,希腊人和罗马人没有这个数字。
6-19

缺省访问控制
自Java 1已开始支持。 较少用到的访问控制方式。 注意:位于其他程序包的派生类也不可访问这些成员。

即使在Java API中也较少用到
例子:java.lang.String static int indexOf(...) static int lastIndexOf(...) 目的:由String和StingBuffer共享该查找代码。 结果:java.lang中的其他类均可调用该方法。
6-10
类的接口与实现

接口与实现的分离
同一接口、多种实现。 OMG IDL:独立于特定语言。

C++和Java语言都支持接口与实现的分离
但两种语言选择的途径不相同。
6-11
• •
类:以保留字class声明。
提供了对象的实现。
接口:以保留字interface声明。
描述了对象的接口(对外的、公有的接口)。 由于缺乏实现,不能通过接口创建对象实例(但允许将接口作为对象 的类型)。
type IntegerSet = { sort 零元操作相当于常量 零元操作相当于常量 int, bool, set operations zero: → int true: → bool false: → bool empty: → set pred: int → int succ: int → int insert: set × int → set remove: set × int → set has: set × int → bool axioms insert(insert(s, i), i) = insert(s, i) insert(insert(s, i), j) = insert(insert(s, j), i) has(remove(insert(s, i), j), i) = true ⇒ remove(insert(s, i), j) = insert(remove(s, j), i) i = j ⇒ remove(insert(s, i), j) = remove(s, j) remove(empty, i) = empty has(insert(s, i), i) = true has(remove(insert(s, i), j), i) = true ⇒ has(insert(s, i), j) = has(s, j) has(empty, i) = false succ(pred(i)) = i pred(succ(i)) = i }
default
不加缀任何访问控制保留字,又称friendly access或package access。 这些成员只能由同一程序包(包括默认程序包)中的类访问。 对本程序包的类而言,效果相当于public。 对其他程序包的类而言,效果相当于private。
• private
4P 4P
这些成员是除自身外任何类都不允许访问。 只有类自己的那些方法体中才可访问这些成员。
静态的概念 静态的概念

对象:描述实体的具体个体
动态的概念 动态的概念
6-3
观察:无处不在的实体!

现实世界:
学生、教师、 飞机、发动机、雷达、传感器、 电视机、钟表、 库存商品、入库单、记帐凭证、...
• •
思维世界:
复数、矩阵、 随机数发生器、 线性链表、堆栈、队列、...
抽象:建模的主要思维方式
依次为:public、protected、friendly、private 再依次为:static、非static。
6-24
利用访问控制实现信息隐藏的好处
• •
支持大型程序设计(programming in the large)
让每一程序员只看到自己应该看到的东西!
限制变动的影响范围:
当属性表示方法发生变化时只需修改类中方法, 只要所有公有方法保持不变,变化不会影响其他程序。
6-15
(续上页) // 领料出库,出库数量为qty,返回出库成本 public double checkOut(double qty) { // 如果数量余额不足则不作出库 if (quantity < qty) return 0; // 计算出库的成本金额, double amt = amount; if (qty < quantity) { // 保证存货数量余额为0时存货金额余额也为0 double price = ((long)(amount/quantity*100)) / 100.0; amt = qty * price; } // 减少库存数量与金额 quantity -= qty; amount -= amt; return amt; } // 查询当前的存货数量余额 public double getQuantity() { return quantity; } // 查询当前的存货金额余额 public double getAmount() { return amount; } }
6-16
类作用域
• •
类中声明的数据或方法成员的作用域涵盖整个类
声明在前的方法体中,可调用声明在后的方法或数据成员。
类中声明的形式参数或局部变量隐藏同名数据成员
区别: 禁止方法体中声明的局部变量隐藏同名的形式参数! 禁止在内层块中声明的变量隐藏外层声明的同名变量。
6-17
Name Shadowing
6-1
第六讲 类与对象(I) • • • • • • •
类与对象概述 类的声明 ★ 类成员的访问控制 ★★ 使用对象实例 静态成员 ★★ 类也是一个对象 完整的类声明
6-2
6.1 类与对象概述

类:描述实体的抽象概念
成员:数据成员+方法成员 数据成员:实体的属性 方法成员:实体的行为 实体的约束只能隐式地表达在属性或行为中。
6-4
抽象与抽象层次

IEEE-CS/ACM“91计算教学计划”
12个重复出现的核心概念:绑定、空间有序、时间有序、重用、折衷、... 抽象层次(levels of abstraction): 是软件工程乃至整个计算机科学的最重要思维方式(之一)。
• •
抽象(abstraction)
将复杂事物的一个或多个特性去掉,而只留意其他剩余特性的行为或过程。 即将若干有区别的事物的共性抽取出来,并加以孤立地考察的行为或过程。
Lecture Notes on
Object-Oriented Programming & Design
( Master of Software Engineering ’2005 )
Dr. Li Wenjun
lnslwj@zsu.edu.cn Department of Computer Science Zhongshan University, GZ 510275

类与接口的关系:类实现(implements)接口。
一个类可以实现多个接口:从不同角度看问题。 一个接口也可以由多个类实现:不同的实现途径。 但Java语言的接口与类必须使用不同的名字!
6-12
6.2 类的声明

数据成员
描述实体的属性。 变量的声明与初始化

方法成员
描述实现的行为。 方法的声明
6-13
set()中的x引用形式参数而不是 数据成员; get()第1行的x引用数据成员, 第3行的x引用局部变量。
6-18
开放性
6.3 类成员的访问控制
• public
这些成员能由所有的类访问。
• protected •
不同于C++: 不同于C++: C++没有程序包 C++没有程序包
这些成员只能由派生类或同一程序包中的类访问。 对其他程序包的派生类而言,效果相当于public。 对其他程序包的非派生类而言,效果相当于private。
真的需要对外暴露数据?
• • •
应仔细研究后再作出决策! 只读公开:
仍声明为私有的或受保护的;另提供一个公有的getter。
ቤተ መጻሕፍቲ ባይዱ
可读写公开:
要么 将数据成员声明为公有的; 要么 将数据声明为私有的或受保护的, 然后提供一个公有的getter和一个公有的setter。
6-23
类成员的典型出现次序
• •
例子一:银行帐户
// 银行帐户 public class Account { // 银行帐户的属性 private double balance = 0; // 存款余额
// 向帐户中存款,存款金额为amount public void deposit(double amount) { balance = balance + amount; } // 从帐户中取款amount元,成功返回true,否则返回false public boolean withdraw(double amount) { if (amount <= balance) { balance = balance - amount; return true; } else return false; } // 查询帐户的当前余额 public double getBalance() { return balance; } }
6-8
ADT
Class
Object
6-9
类在程序中的作用

作为模块化机制
封装:将相关的数据以及作用在这些数据上的操作组织在一起。 信息隐藏:对象的某些特征只在对象内部可见。 外部程序只能访问那些允许它访问的特征; 通常由访问控制(access control)实现。

作为类型定义机制
类作为一种模板,用于创建对象实例。 提供相应的类型检查。
6-14
例子二:库存货品
// 库存货品 public class Inventory { // 存货的属性 private double quantity = 0; private double amount = 0;
// 存货的数量 // 存货的金额
// 验收入库,入库数量和金额分别为qty和amt public void checkIn(double qty, double amt) { quantity += qty; amount += amt; } (未完待续)
6-6
不同的抽象层次
• •
Bertrand Meyer:一个类是抽象数据类型的一个实现。 抽象数据类型(Abstract Data Type)
ADT=名字+基调+公理等式 基调=类别集+运算基调集 代数语义学以ADT为主要研究对象。

抽象之处
未定义数据的具体表达方式; 未定义操作的具体实现方法。
6-7
6-20
类成员访问控制的编程模式
总体设计思想

尽可能保持私有性
只要能满足需要,就应选择开放性最低的访问控制。 仅将你认为客户程序需要使用的方法对外公开。
6-21
最简单、实用的编程模式
• •
将所有数据成员声明为私有的或受保护的
以实现信息隐藏。
将所有方法成员声明为公有的
以供其他程序片段使用。
6-22
相关文档
最新文档