计算器与工程问题解析导论

35
计计计计计计计计计计计计 计计计 计计计计计 史史史 .R. 史史史史 史史史 . 史史史史 Prof. Steven R. Lerman and Dr. V. Judson Harward

description

计算器与工程问题解析导论. 第五课 类别与对象. 史帝芬 .R. 雷门教授 贾德森 . 霍华教授 Prof. Steven R. Lerman and Dr. V. Judson Harward. 物件. 对象是「东西」 回想一下在第一讲中所提到关于梁,楼板等的描述。 我们将程序问题分解成一组对象,这些对象可以做为整个状态的「自然」代表性质。举例来说 : 一幢建筑物 物件列表 每一个对象可以包含其它对象。将它们列出来。 通过路由器的数据封包 物件列表 每一个对象可以包含其它对象。将它们列出来。. 物件. 一幢建筑物 - PowerPoint PPT Presentation

Transcript of 计算器与工程问题解析导论

Page 1: 计算器与工程问题解析导论

计算器与工程问题解析导论

第五课

类别与对象

史帝芬 .R.雷门教授贾德森 .霍华教授Prof. Steven R. Lerman

and

Dr. V. Judson Harward

Page 2: 计算器与工程问题解析导论

物件

• 对象是「东西」– 回想一下在第一讲中所提到关于梁,楼板等的描述。

• 我们将程序问题分解成一组对象,这些对象可以做为整个状态的「自然」代表性质。举例来说 :– 一幢建筑物

• 物件列表– 每一个对象可以包含其它对象。将它们列出来。

– 通过路由器的数据封包• 物件列表

– 每一个对象可以包含其它对象。将它们列出来。

Page 3: 计算器与工程问题解析导论

物件

• 一幢建筑物– 物件有:梁、版、墙、窗、管线、风管、热水锅炉、… ..

• 窗户包含了玻璃板、窗框• 构件 (像玻璃板 )是有属性的,如:外层、高度、宽度

• 通过路由器的数据封包– 物件有:网络进入的连结与送出的连结,路由器。这每一个对象可包含其它的对象:

• 网络连结:包含了资料封包• 路由器:包含了封包序列、缓冲器、处理器

Page 4: 计算器与工程问题解析导论

范例:银行

• 顾客:– 数据域:

• 资料列表– 方法或动作

• 资料列表• 柜台:

– 数据域:• 资料表列

– 方法:• 资料表列

• 交易:– 数据域:

• 资料列表– 方法:

• 资料列表

Page 5: 计算器与工程问题解析导论

范例:银行

• 顾客:– 数据域:

• 姓名、地址、职业、生日……

– 方法或动作• 开账号、变更地址、变更姓名、删除账号

• 柜台:– 数据域:

• 顾客、对帐、打字、交易– 方法:

• 新增、关闭、对帐检查、交易报告• 交易:

– 数据域:• 存款、提款、转帐、支票兑现、自动提款

– 方法:• 新增、执行交易

Page 6: 计算器与工程问题解析导论

范例:鸟

Page 7: 计算器与工程问题解析导论

建立对象模型

• 建立对象模型 (选择对的问题代表 )就像一般地建立模型– 一般来说没有固定的单一「正确」答案 (即使是我们的问题集也

是 )– 有弹性的、正确的、有效率的标准形态 /范例可以参考。

• 稍后我们会介绍给你「软件形态」– Java中已有许多的标准对象– 你可以建立属于自己的 Java对象库以供在未来的程序中使用。

Page 8: 计算器与工程问题解析导论

类别

• 类别是由对象所构成的型态或样版– 你可以用一个模拟来做出很多鸟

• 一个鸟的类别 (或有更多的鸟的种类 )• 许多鸟的对象 (鸟的实例 )• 模拟

– 另一个范例• JOptionPane 是个属于 Swing套件中的类别。一个程序可能有许多的对话窗,每一个对话窗都是一个 JOptionPane类别的对象。

Page 9: 计算器与工程问题解析导论

定义类别

• 类别包含了:– 数据 (构件、字段 )

• 主要的数据型态,例如:整数或双精度 (如鸟的重量 )• 哪些物件 (如鸟的嘴 )

– 方法 ( 功能、程序 )• 对象可以执行的动作 (如鸟的飞行 /移动 )

Page 10: 计算器与工程问题解析导论

定义类别

• 类别来自于:– Java 类别库: JOptionPane, Vector(向量 ), Array(数组 )等。那里有数以千计的类别 ( 详 Javadoc) 。

– 其它资源的类别库: Video(影像 )等– 自行撰写的类别库。

• 类别在问题的叙述中通常是一个名词 (如:鸟 )• 方法则通常是动词 (如:飞 )

Page 11: 计算器与工程问题解析导论

建立类别

• 类别会对使用者 (程序设计师使用预先写好的类别 )隐藏其执行的细节:– 其数据不能直接存取,而且对「外部」对象或程序也不知道其细

节。– 其数据几乎均为 private( 关键词 )

Page 12: 计算器与工程问题解析导论

建立类别

• 藉由呼叫其方法来使用该对象– 外部使用者知道对象有什么方法,以及会传回何种结果,就是这

样 (通常来说 )。• 「外人」并不知道这些方法是如何被撰写的细节。

– 方法通常是 public ( 关键词 )• 藉由独立这些对象程序写作的细节,使得建立一支大型的程序变得更简单,也可以再利用先前工作中建立的对象。

• 这就称为「数据封装 (encapsulation) 」或「信息隐藏 (information hiding) 」

Page 13: 计算器与工程问题解析导论

类别与对象

• 类别是一种「型态」 (pattern)– 一个类别可以拥有许多储存在类别内的数据项– 一个类别可以拥有许多操作 (或修改 )其数据与结果回传的方法

• 对象是类别的一部份– 对象拥有自己的数据、类别方法以及身份辨识 (一个名称 )

Page 14: 计算器与工程问题解析导论

类别与对象

• Java类别库中的类别与你自行建立的并没有任何差别– 当你建立了一个类别 , 你就是在 Java中正在定义一个新的数据型态

– 实质上 , 你正在扩展 Java 语言• 类别也可以从其它的类别中来建立。

– 从其它的类别所建立的类别就扩展了原来的类别。– 这就称为「继承」 (inheritance) ,容后再述。

Page 15: 计算器与工程问题解析导论

使用已存在的类别

• 内建的类别会比你自己撰写的更为理论与一般化。• BigInteger是一个处理任意大整数的 Java类别

– 使用这个类别而不要用你自己所写的来处理任意的运算

Page 16: 计算器与工程问题解析导论

使用已存在的类别

• 要使用对象:– 首先要建构对象并指定他们的起始状态

• 建构子 (constructor) 是一个特殊的方法,是用来建构与设定对象的起始状态。• 他们可能需要自变量 (参数 )

– 然后对对象加上方法• 就好像「传送讯息」给对象来唤起他们的动作

Page 17: 计算器与工程问题解析导论

物件 BigInteger 的建构子

• 要建构一个新的 BigInteger 对象,有两件事情是必要的:– 建立对象 (使用它的建构子 )

new BigInteger(“1000000000000”);

// ‘new’ 会配置内存并呼叫建构子– 给定对象一个名称或识别代号

BigInteger a;

// 对象的名称是对该对象的参考// BigInteger 为 a 的数据型态

Page 18: 计算器与工程问题解析导论

物件 BigInteger 的建构子

– 将两件必要的事情结合为一件:BigInteger a = new BigInteger(“1000000000000”);– 现在我们拥有了一个内含值为 1,000,000,000,000的物件BigInteger。我们现在可以对这个对象设定方法。

Page 19: 计算器与工程问题解析导论

• 方法是使用点 (.) 运算子来唤起的– 方法通常会用括号” ()”来结尾

BigInteger a= new BigInteger(“1000000000000”);

BigInteger z= new BigInteger(“23”);

BigInteger c= a.add(z); // c= a + z

If (z.isProbablePrime(15)) // z 是质数吗 ? System.out.println(“z is probably prime”);

• Public的数据域位也可以利用点运算子来唤起。– 在字段名称后不需要加上括号int j – a.somePublicField; // 只是范例

使用方法

Page 20: 计算器与工程问题解析导论

对象与名称

Page 21: 计算器与工程问题解析导论

对象与名称

Page 22: 计算器与工程问题解析导论

对象与名称

Page 23: 计算器与工程问题解析导论

对象与名称

Page 24: 计算器与工程问题解析导论

对象与名称

Page 25: 计算器与工程问题解析导论

对象与名称

Page 26: 计算器与工程问题解析导论

使用 BigInteger 类别 ( 编注 :for random 与 random 漏译 , 已改正 )

给 BigInteger 使用

nbr 随机数产生器

c=b+a

质数

为了使用随机数而引入

取得随机数

Page 27: 计算器与工程问题解析导论

练习一:现有的类别

• 利用 BigDecimal类别 ( 浮点数 )来:– 建构 BigDecimal a=13 x 10500– 以随机数建构 BigDecimal b

• 提示:建构一个随意的 BigInteger ,然后使用适当的 BigDecimal 建构子。详见 Javadoc 。

– 计算 BigDecimal c = a+b– 计算 BigDecimal d = c/a

• 在 Javadoc 中查询进位的型式– 分别计算出 a,b,c,d 后将结果打印出来

Page 28: 计算器与工程问题解析导论

练习一:现有的类别

• 阶段式地撰写程序:– 建构 a, 将结果印出来。编译及除错

• 千万不要去数到底有多少个零 !

– 再建构 b,将结果印出来。编译及除错– 计算其相加与相除。编译及除错

Page 29: 计算器与工程问题解析导论

练习二:撰写一个类别

• 在家庭作业中,你将要开始撰写自己的类别。– 你已经在所有的练习中看过类别的示范,但它们并不是典型的

• 它们都只有单一的方法 , main()

– 大部份的类别是没有main( )这个方法的• 建立一支程序,你将要撰写数个类别,而其中一个包含有

main( )的方法。

Page 30: 计算器与工程问题解析导论

Point 类别public class SimplePoint {

private double x, y; // 资料成员public SimplePoint() { // 建构子

x= 0.0;y= 0.0; }

// 方法public double getX() { return x;}public double getY() { return y;}public void setX(double xval) { x= xval;}public void setY(double yval) { y= yval;}public void move(double deltaX, double deltaY) {

x += deltaX;y += deltaY; }

} // SimplePoint 类别的结束

// 这并不是一支程序,因为它没有 main( )// 但是可以藉由 main( )被类别使用

Page 31: 计算器与工程问题解析导论

Point 类别 , main( )

Page 32: 计算器与工程问题解析导论

练习二

• 使用极坐标来取代卡氏坐标,撰写一个不同的SimplePoint 类别。– 如前述 SimplePoint 类别般地执行相同的 public 方法– 使用 r 及 theta 做为 private 数据域位– 回顾:

• x = r cos(theta)• y = r sin(theta)• r = sqrt(x2 + y2)• theta= tan-1(y/x)

– 使用 Java 的 Math类别 ( 前缀为大写 M)• 使用 Math.atan2( ) 来表示 arctan 的功能

• 使用与前述相同的 main( ) 。

Page 33: 计算器与工程问题解析导论

为何要做这练习 ?

• 透过建立一个具有 public方法但含有 private数据的类别,你只是指定一个接口,而非执行。– 如果你要改变执行,你可以用这样的方式来做而且不用修改相关

的程序代码,只要维持接口 (set of methods) 相同。– 变更坐标系统、计算方法等是相当平常的,如同这个范例一样。这样可让软件保有弹性来成长与改变。

Page 34: 计算器与工程问题解析导论

Point 类别 , 以极坐标计算 ( 编注 :下方蓝色内文漏译 , 已修正 )class SimplePoint {

private double r, theta; // 资料成员为 publicSimplePoint() { // 建构子

r= 0.0;theta= 0.0; }

// 方法 (以弪度值为自变量的三角函数 )public double getX() { return r* Math.cos(theta);}public double getY() { return r* Math.sin(theta);}public void setX(double xval) {

double yval= r*Math.sin(theta);r= Math.sqrt(xval*xval + yval*yval);theta= Math.atan2(yval, xval); }

Page 35: 计算器与工程问题解析导论

Point 类别 , 以极坐标计算 ( 续 )public void setY(double yval) {

double xval= r*Math.cos(theta);r= Math.sqrt(xval*xval + yval*yval);theta= Math.atan2(yval, xval); }

public void move(double deltaX, double deltaY) {double xval= r*Math.cos(theta);double yval= r*Math.sin(theta);xval += deltaX;yval += deltaY;r= Math.sqrt(xval*xval + yval*yval);theta= Math.atan2(yval, xval);}

}

// 可以从前述相同的 main()来唤起// 而且会产生相同的结果 (除了进位错误外 )

Java? 是 Sun Microsystems, Inc. 在美国及其它国家的注册商标。