R——判断数据是否符合某一分布

首先这篇文章判断数据是否服从某一分布(二)——简单易用fitdistrplus包 - ywliao - 博客园 (cnblogs.com)

有提到fitdistrplus的应用,适用于基本的方法。本文章想根据他写的部分进行一定的补充。

如果从网络上找到了保险公司损失数据,对于损失会有频率(每天发生损失的次数,ex:1.1号发生损失8次,1.2号发生损失3次)和严重性(每次损失的金额,ex:1000,4000,200等)。如果想预测一年总损失,那就需要对这些损失的分布进行判断,选择最适合的分布。

这个代码同时会算出P值,AIC等指标可以用来检测拟合结果哦

首先导入

library(fitdistrplus) 

library(actuar)
library(eva)

  1. 泊松分布
    fit_poi<-fitdist(DATA,'pois')
    summary(fit_poi)
    gofstat(fit_poi)
  2. 负二项分布
    fit_nb<-fitdist(DATA,'nbinom')
    summary(fit_nb)
    gofstat(fit_nb)

3.正态分布

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
本书从函数功能、函数格式、参数说明、注意事项、Excel 版本提醒、案例应用、交叉参考7 个方面,全面、细致地介绍了Excel 2016/2013/2010/2007/2003 中公式和函数的使用方法、实际应用和操作技巧。最后3 章还将公式与函数的应用扩展到了条件格式、数据验证及图表中,以便使它们发挥更强大的功能。本书采用理论与实践相结合的方式,提供了457 个案例,涉及多个行业,读者可以根据书中的案例举一反三,将其直接应用到实际工作中,有效提高学习效果与实际应用能力。 本书既可以作为函数速查工具手册,又可以作为丰富的函数应用案例宝典,适合对Excel 公式与函数有需求的读者阅读。 第1章 公式与函数基础 1 1.1 了解公式 1 1.1.1 公式的组成部分 1 1.1.2 数据类型及其相互转换 2 1.1.3 运算符及其优先级 3 1.1.4 普通公式与数组公式 5 1.1.5 单个单元格公式与多个单元格公式 5 1.1.6 Excel对数字精度、公式与函数等方面的限制 5 1.2 输入与编辑公式 6 1.2.1 A1引用样式与R1C1引用样式 6 1.2.2 输入公式 8 1.2.3 修改公式 9 1.2.4 移动和复制公式 9 1.2.5 删除公式 12 1.2.6 改变公式的计算方式 13 1.3 在公式中使用函数 14 1.3.1 为什么使用函数 14 1.3.2 函数的类型 14 1.3.3 函数的参数 15 1.3.4 在公式中输入函数 16 1.4 在公式中使用名称 18 1.4.1 名称的作用范围 19 1.4.2 命名区域 19 1.4.3 命名公式 20 1.4.4 命名常量 21 1.4.5 将名称应用到公式中 21 1.5 使用数组公式 23 1.5.1 单个单元格数组公式与多单元格数组公式 23 1.5.2 数组的维数 24 1.5.3 输入数组公式 25 1.5.4 修改数组公式 25 1.5.5 扩展或缩小多单元格数组公式 26 1.5.6 选择数组公式所在区域 27 1.5.7 使用常量数组 27 1.6 创建跨工作表和跨工作簿引用的公式 28 1.6.1 创建引用其他工作表中的数据的公式 28 1.6.2 创建引用其他工作簿中的数据的公式 29 1.6.3 创建对多个工作表中相同单元格区域的三维引用 30 1.6.4 更新跨工作簿引用的公式 31 1.7 审核公式 31 1.7.1 使用公式错误检查器 32 1.7.2 定位特定类型的数据 33 1.7.3 追踪单元格之间的关系 33 1.7.4 监视单元格内容 35 1.7.5 使用公式求值器 36 1.8 处理公式中的错误 36 1.8.1 括号不匹配 37 1.8.2 单元格被#符号填满 37 1.8.3 空白但非空的单元格 37 1.8.4 显示值与实际值 38 1.8.5 返回错误值 39 1.8.6 循环引用 41 1.9 公式使用技巧 42 1.9.1 在多个单元格中输入同一个公式 42 1.9.2 显示公式而不是值 42 1.9.3 查看公式的中间结果 42 1.9.4 将公式转换为值 43 1.9.5 复制公式但不使用相对引用 43 1.9.6 隐藏公式 44 1.9.7 禁止用户修改公式 45 第2章 数学和三角函数 46 2.1 常规计算 48 2.1.1 SIGN——返回数字的符号 48 2.1.2 ABS——计算数字的绝对值 49 2.1.3 SUM——计算数字之和 50 2.1.4 PRODUCT——计算数字之积 52 2.1.5 SQRT——计算正平方根 52 2.1.6 MOD——返回商的余数 53 2.1.7 QUOTIENT——返回商的整数部分 55 2.1.8 GCD——计算最大公约数 56 2.1.9 LCM——计算最小公倍数 57 2.1.10 SUMIF——按给定条件对指定单元格求和 57 2.1.11 SUMIFS——按多个条件对指定单元格求和 59 2.1.12 SUMPRODUCT——计算数组元素的乘积之和 60 2.1.13 SUMSQ——计算参数的平方和 61 2.1.14 SUMXMY2——计算数组对应值之差的平方和 62 2.1.15 SUMX2MY2——计算数组对应值的平方差之和 63 2.1.16 SUMX2PY2——计算数组对应值的平方和之和 63 2.1.17 SERIESSUM——计算基于公式的幂级数之和 64 2.2 舍入计算 65 2.2.1 INT——返回永远小于等于原数字的最接近的整数 65 2.2.2 TRUNC——返回数字的整数部分 66 2.2.3 ROUND——按指定位数对数字进行四舍五入 67 2.2.4 ROUNDDOWN——以绝对值减小的方向按指定位数舍入数字 68 2.2.5 ROUNDUP——以绝对值增大的方向按指定位数舍入数字 69 2.2.6 MROUND——舍入到指定倍数的数字 70 2.2.7 CEILING——以绝对值增大的方向按指定倍数舍入 71 2.2.8 CEILING.PRECISE——以算数值增大的方向按指定倍数舍入 73 2.2.9 CEILING.MATH——以绝对值或算数值增大的方向按指定倍数舍入 73 2.2.10 FLOOR——以绝对值减小的方向按指定倍数舍入 74 2.2.11 FLOOR.PRECISE——以算数值减小的方向按指定倍数舍入 75 2.2.12 FLOOR.MATH——以绝对值或算数值减小的方向按指定倍数舍入 76 2.2.13 EVEN——以绝对值增大的方向舍入到最接近偶数 77 2.2.14 ODD——以绝对值增大的方向舍入到最接近奇数 78 2.3 指数与对数计算 79 2.3.1 POWER——计算数字的乘幂 79 2.3.2 EXP——计算e的n 次方 80 2.3.3 LN——计算自然对数 81 2.3.4 LOG——计算以指定数字为底的对数 81 2.3.5 LOG10——计算以10为底的对数 82 2.4 阶乘、矩阵与随机数 83 2.4.1 COMBIN——计算给定数目对象的组合数 83 2.4.2 COMBINA——计算给定数目对象具有重复项的组合数 84 2.4.3 FACT——计算数字的阶乘 84 2.4.4 FACTDOUBLE——计算数字的双倍阶乘 85 2.4.5 MULTINOMIAL——计算多个数字和的阶乘与各数字阶乘乘积的比值 86 2.4.6 MDETERM——计算数组的矩阵行列式的值 86 2.4.7 MINVERSE——计算数组的逆矩阵 87 2.4.8 MMULT——计算两个数组的矩阵乘积 88 2.4.9 MUNIT——返回指定维度的单位矩阵 89 2.4.10 RAND——返回0到1之间的一个随机数 89 2.4.11 RANDBETWEEN——返回某个范围内的随机数 91 2.5 三角函数计算 91 2.5.1 DEGREES——将弧度转换为角度 91 2.5.2 RADIANS——将角度转换为弧度 92 2.5.3 SIN——计算给定角度的正弦值 93 2.5.4 ASIN——计算数字的反正弦值 93 2.5.5 SINH——计算数字的双曲正弦值 94 2.5.6 ASINH——计算数字的反双曲正弦值 95 2.5.7 COS——计算给定角度的余弦值 95 2.5.8 ACOS——计算数字的反余弦值 96 2.5.9 COSH——计算数字的双曲余弦值 97 2.5.10 ACOSH——计算数字的反双曲余弦值 97 2.5.11 TAN——计算给定角度的正切值 98 2.5.12 ATAN——计算数字的反正切值 99 2.5.13 TANH——计算数字的双曲正切值 99 2.5.14 ATANH——计算数字的反双曲正切值 100 2.5.15 ATAN2——计算给定坐标的反正切值 101 2.5.16 ACOT——计算数字的反余切值 102 2.5.17 ACOTH——计算数字的反双曲余切值 102 2.5.18 COT——计算给定角度的余切值 103 2.5.19 COTH——计算数字的双曲余切值 104 2.5.20 SEC——计算给定角度的正割值 105 2.5.21 SECH——计算给定角度的双曲正割值 105 2.5.22 CSC——计算给定角度的余割值 106 2.5.23 CSCH——计算给定角度的双曲余割值 107 2.6 其他计算 108 2.6.1 PI——返回pi的值 108 2.6.2 SQRTPI——计算某数与pi的乘积的平方根 108 2.6.3 SUBTOTAL——返回指定区域的分类汇总结果 109 2.6.4 AGGREGATE——返回指定区域的分类汇总结果 111 2.6.5 ROMAN——将阿拉伯数字转为文本型罗马数字 113 2.6.6 ARABIC——将罗马数字转换为阿拉伯数字 114 2.6.7 BASE——将一个数转换为给定基数的文本格式 115 2.6.8 DECIMAL——将给定基数的文本转换为十进制数 116 第3章 日期和时间函数 117 3.1 了解Excel日期系统 118 3.1.1 Excel提供的两种日期系统 118 3.1.2 了解日期和时间序列号 119 3.1.3 输入与设置日期和时间 120 3.1.4 两位数年份问题 121 3.2 返回当前的日期、时间和指定的日期、时间 121 3.2.1 NOW——返回当前日期和时间 121 3.2.2 TODAY——返回当前日期 123 3.2.3 DATE——返回指定日期的序列号 124 3.2.4 TIME——返回指定时间的序列号 125 3.3 返回日期和时间的某个部分 126 3.3.1 YEAR——返回年份 126 3.3.2 MONTH——返回月份 127 3.3.3 DAY——返回日期中具体的某一天 129 3.3.4 WEEKDAY——返回当前日期是星期几 130 3.3.5 HOUR——返回小时数 131 3.3.6 MINUTE——返回分钟数 131 3.3.7 SECOND——返回秒数 132 3.4 文本与日期、时间格式间的转换 133 3.4.1 DATEVALUE——将文本格式的日期转换为序列号 133 3.4.2 TIMEVALUE——将文本格式的时间转换为序列号 134 3.5 其他日期函数 135 3.5.1 DATEDIF——计算开始和结束日期之间的时间间隔 135 3.5.2 DAYS360——以360天为准计算两个日期间天数 136 3.5.3 DAYS——计算两个日期之间的天数 137 3.5.4 EDATE——计算从指定日期向前或向后几个月的日期 138 3.5.5 DATESTRING——将指定日期的序列号转换为文本日期 139 3.5.6 EOMONTH——计算从指定日期向前或向后几个月后的那个月最后一天的日期 140 3.5.7 NETWORKDAYS——计算日期间的所有工作日数 141 3.5.8 NETWORKDAYS.INTL——计算日期间的所有工作日数,使用参数指明周末的日期和天数 142 3.5.9 WEEKNUM——返回日期在一年中是第几周 144 3.5.10 ISOWEEKNUM——返回日期在一年中的ISO周数 145 3.5.11 WORKDAY——计算与指定日期相隔数个工作日的日期 146 3.5.12 WORKDAY.INTL——计算与指定日期相隔数个工作日的日期,使用参数指明周末的日期和天数 147 3.5.13 YEARFRAC——计算从开始日期到结束日期所经历的天数占全年天数的百分比 149 第4章 逻辑函数 151 4.1 逻辑值函数 151 4.1.1 TRUE——返回逻辑值TRUE 151 4.1.2 FALSE——返回逻辑值FALSE 152 4.2 条件判断函数 153 4.2.1 NOT——对逻辑值求反 153 4.2.2 AND——判断多个条件是否同时成立 154 4.2.3 OR——判断多个条件中是否至少有一个条件成立 155 4.2.4 XOR——判断多个条件中是否有一个条件成立 156 4.2.5 IF——根据条件判断而返回不同结果 156 4.2.6 IFNA——判断公式是否出现#N/A错误 158 4.2.7 IFERROR——根据公式结果返回不同内容 158 第5章 文本函数 160 5.1 返回字符或字符编码 162 5.1.1 CHAR——返回与ANSI字符编码对应的字符 162 5.1.2 UNICHAR——返回与Unicode字符编码对应的字符 163 5.1.3 CODE——返回与字符对应的ANSI字符编码 163 5.1.4 UNICODE——返回与字符对应的Unicode字符编码 164 5.2 返回文本内容 165 5.2.1 LEFT——从文本左侧起提取指定个数的字符 165 5.2.2 LEFTB——从文本左侧起提取指定字节数字符 166 5.2.3 LEN——计算文本中的字符个数 167 5.2.4 LENB——计算文本中代表字符的字节数 168 5.2.5 MID——从文本指定位置起提取指定个数的字符 169 5.2.6 MIDB——从文本指定位置起提取指定字节数的字符 170 5.2.7 RIGHT——从文本右侧起提取指定个数的字符 170 5.2.8 RIGHTB——从文本右侧起提取指定字节数字符 171 5.2.9 REPT——生成重复的字符 172 5.3 合并文本 173 5.3.1 CONCATENATE——将多个文本合并到一处 173 5.4 转换文本格式 174 5.4.1 ASC——将全角字符转换为半角字符 174 5.4.2 WIDECHAR——将半角字符转换为全角字符 175 5.4.3 PHONETIC——返回文本中的拼音字符 176 5.4.4 BAHTTEXT——将数字转换为泰语文本 176 5.4.5 DOLLAR——将数字转换为带美元符号$的文本 176 5.4.6 RMB——将数字转换为带人民币符号¥的文本 177 5.4.7 NUMBERSTRING——将数值转换为大写汉字 178 5.4.8 NUMBERVALUE——以与区域设置无关的方式将文本转换为数字 179 5.4.9 T——将参数转换为文本 179 5.4.10 LOWER——将文本转换为小写 180 5.4.11 UPPER——将文本转换为大写 180 5.4.12 PROPER——将文本中每个单词的首字母转换为大写 181 5.4.13 VALUE——将文本型数字转换为数值 182 5.4.14 TEXT——多样化格式设置函数 183 5.4.15 FIXED——将数字按指定的小数位数取整 184 5.5 查找与替换文本 185 5.5.1 EXACT——比较两个文本是否相同 185 5.5.2 FIND——以字符为单位并区分大小写地查找指定字符的位置 186 5.5.3 FINDB——以字节为单位并区分大小写地查找指定字符的位置 187 5.5.4 REPLACE——以字符为单位根据指定位置进行替换 188 5.5.5 REPLACEB——以字节为单位根据指定位置进行替换 189 5.5.6 SEARCH——以字符为单位不区分大小写地查找指定字符的位置 189 5.5.7 SEARCHB——以字节为单位不区分大小写地查找指定字符的位置 191 5.5.8 SUBSTITUTE——以指定文本进行替换 191 5.6 删除文本中的字符 192 5.6.1 CLEAN——删除无法打印的字符 192 5.6.2 TRIM——删除多余的空格 193 第6章 查找和引用函数 194 6.1 查找表中数据 195 6.1.1 CHOOSE——根据序号从列表中选择对应的内容 195 6.1.2 LOOKUP——仅在单行单列中查找(向量形式) 200 6.1.3 LOOKUP——仅在单行单列中查找(数组形式) 203 6.1.4 HLOOKUP——在区域或数组的行中查找数据 204 6.1.5 VLOOKUP——在区域或数组的列中查找数据 205 6.1.6 MATCH——返回指定内容所在的位置 208 6.1.7 INDEX——返回指定位置中的内容(数组形式) 212 6.1.8 INDEX——返回指定位置中的内容(引用形式) 213 6.2 引用表中数据 214 6.2.1 ADDRESS——返回与指定行号和列号对应的单元格地址 214 6.2.2 AREAS——返回引用中包含的区域数量 217 6.2.3 COLUMN——返回单元格或单元格区域首列的列号 217 6.2.4 COLUMNS——返回数据区域包含的列数 235 6.2.5 ROW——返回单元格或单元格区域首行的行号 219 6.2.6 ROWS——返回数据区域包含的行数 221 6.2.7 OFFSET——根据给定的偏移量返回新的引用区域 223 6.2.8 TRANSPOSE——转置数据区域的行列位置 227 6.2.9 INDIRECT——返回由文本值指定的引用 227 6.2.10 FORMULATEXT——返回给定引用公式的文本形式 229 6.2.11 GETPIVOTDATA——返回数据透视表中的数据 230 6.2.12 HYPERLINK——为指定内容创建超链接 231 6.2.13 RTD——返回支持COM自动化程序的实时数据 233 第7章 信息函数 235 7.1 返回信息 236 7.1.1 CELL——返回单元格格式、位置或内容的信息 236 7.1.2 INFO——返回当前操作环境的相关信息 238 7.1.3 SHEET——返回引用工作表的工作表编号 239 7.1.4 SHEETS——返回引用中的工作表总数 239 7.2 返回各类型的值 240 7.2.1 ERROR.TYPE——返回对应于错误类型的数字 240 7.2.2 N——返回转换为数字的值 241 7.2.3 NA——返回错误值#N/A 242 7.2.4 TYPE——返回表示数据类型的数字 243 7.3 使用IS函数进行各种判断 244 7.3.1 ISBLANK——判断单元格是否为空 244 7.3.2 ISLOGICAL——判断是否为逻辑值 245 7.3.3 ISNUMBER——判断是否为数字 245 7.3.4 ISTEXT——判断是否为文本 246 7.3.5 ISNONTEXT——判断是否为非文本 246 7.3.6 ISFORMULA——判断单元格是否包含公式 247 7.3.7 ISEVEN——判断数字是否为偶数 248 7.3.8 ISODD——判断数字是否为奇数 249 7.3.9 ISNA——判断是否为错误值#N/A 249 7.3.10 ISREF——判断是否为单元格引用 250 7.3.11 ISERR——判断是否为除#N/A以外的其他错误值 250 7.3.12 ISERROR——判断是否为错误值 251 第8章 统计函数 252 8.1 统计数量与频率 255 8.1.1 COUNT——计算参数中包含数字的个数 255 8.1.2 COUNTA——计算参数中包含非空值的个数 257 8.1.3 COUNTBLANK——计算区域中空白单元格的个数 259 8.1.4 COUNTIF——计算满足给定条件的单元格的个数 259 8.1.5 COUNTIFS——计算满足多个给定条件的单元格的个数 262 8.1.6 FREQUENCY——以垂直数组形式返回数据的频率分布 263 8.2 统计均值和众数 264 8.2.1 AVEDEV——计算一组数据与其平均值的绝对偏差的平均值 264 8.2.2 AVERAGE——计算参数的平均值 265 8.2.3 AVERAGEA——计算参数中非空值的平均值 266 8.2.4 AVERAGEIF——计算满足给定条件的所有单元格的平均值 267 8.2.5 AVERAGEIFS——计算满足多个给定条件的所有单元格的平均值 268 8.2.6 GEOMEAN——计算几何平均值 269 8.2.7 HARMEAN——计算调和平均值 270 8.2.8 TRIMMEAN——计算内部平均值 271 8.2.9 MEDIAN——返回中值 272 8.2.10 MODE.SNGL——返回数据中出现次数最多的值 273 8.2.11 MODE.MULT——返回数据中出现频率最高或重复出现的数值的垂直数组 275 8.3 统计极值与排位 276 8.3.1 MAX——返回一组数字中的最大值 276 8.3.2 MAXA——返回一组非空值中的最大值 277 8.3.3 MIN——返回一组数字中的最小值 278 8.3.4 MINA——返回一组非空值中的最小值 279 8.3.5 LARGE——返回数据集中第k个最大值 279 8.3.6 SMALL——返回数据集中第k个最小值 280 8.3.7 RANK.EQ——返回一个数字在一组数字中的排位 281 8.3.8 RANK.AVG——返回一个数字在一组数字中的排位 282 8.3.9 PERCENTRANK.INC——返回数据集中值的百分比排位 283 8.3.10 PERCENTRANK.EXC——返回数据集中值的百分比排位 284 8.3.11 QUARTILE.INC——返回数据集的四分位数 285 8.3.12 QUARTILE.EXC——返回数据集的四分位数 286 8.3.13 PERCENTILE.INC——返回区域中数值的第k个百分点的值 287 8.3.14 PERCENTILE.EXC——返回区域中数值的第k个百分点的值 288 8.3.15 PERMUT——返回给定数目对象的排列数 288 8.3.16 PERMUTATIONA——返回给定数目对象(含重复)的排列数 289 8.4 统计数据的散布度 290 8.4.1 DEVSQ——计算偏差的平方和 290 8.4.2 STDEV.S——估算基于样本的标准偏差,忽略文本和逻辑值 290 8.4.3 STDEVA——估算基于样本的标准偏差,包括文本和逻辑值 291 8.4.4 STDEV.P——估算基于整个样本总体的标准偏差,忽略文本和逻辑值 292 8.4.5 STDEVPA——估算基于整个样本总体的标准偏差,包括文本和逻辑值 293 8.4.6 VAR.S——计算基于给定样本的方差,忽略文本和逻辑值 294 8.4.7 VARA——计算基于给定样本的方差,包括文本和逻辑值 295 8.4.8 VAR.P——计算基于整个样本总体的方差,忽略文本和逻辑值 296 8.4.9 VARPA——计算基于整个样本总体的方差,包括文本和逻辑值 297 8.4.10 KURT——返回数据集的峰值 298 8.4.11 SKEW——返回分布的不对称度 299 8.4.12 SKEW.P——返回某一分布相对其平均值的不对称度 300 8.5 统计概率分布 300 8.5.1 BINOM.DIST——返回一元二项式分布的概率 300 8.5.2 BINOM.INV——返回使累积二项式分布小于或等于临界值的最小值 301 8.5.3 BINOM.DIST.RANGE——返回二项式分布试验结果的概率 302 8.5.4 NEGBINOM.DIST——返回负二项式分布的概率 303 8.5.5 PROB——返回区域中的数值落在指定区间内的概率 304 8.5.6 GAUSS——返回比标准正态累积分布函数小0.5的值 305 8.5.7 PHI——返回标准正态分布的密度函数值 306 8.5.8 NORM.DIST——返回正态累积分布函数 306 8.5.9 NORM.INV——返回标准正态累积分布的反函数值 307 8.5.10 NORM.S.DIST——返回标准正态累积分布函数 308 8.5.11 NORM.S.INV——返回标准正态累积分布函数的反函数值 309 8.5.12 STANDARDIZE——返回正态化数值 310 8.5.13 LOGNORM.DIST——返回对数累积分布函数 311 8.5.14 LOGNORM.INV——返回对数累积分布函数的反函数 312 8.5.15 HYPGEOM.DIST——返回超几何分布 313 8.5.16 POISSON.DIST——返回泊松分布 314 8.5.17 EXPON.DIST——返回指数分布 315 8.5.18 WEIBULL.DIST——返回韦伯分布 316 8.5.19 GAMMA——返回伽玛函数值 317 8.5.20 GAMMA.DIST——返回伽玛分布函数 318 8.5.21 GAMMA.INV——返回伽玛累积分布函数的反函数值 319 8.5.22 GAMMALN——返回伽玛函数的自然对数 320 8.5.23 GAMMALN.PRECISE——返回伽玛函数的自然对数 320 8.5.24 BETA.DIST——返回β累积分布函数 321 8.5.25 BETA.INV——返回指定β累积分布函数的反函数值 322 8.5.26 CONFIDENCE.NORM——返回总体平均值的置信区间 323 8.5.27 CONFIDENCE.T——返回总体平均值的置信区间 324 8.6 检验数据的倾向性 325 8.6.1 CHISQ.DIST.RT——返回x2分布的右尾概率 325 8.6.2 CHISQ.DIST——返回x2分布 326 8.6.3 CHISQ.INV.RT——返回x2分布的右尾概率的反函数值 326 8.6.4 CHISQ.INV——返回x2分布的左尾概率的反函数值 327 8.6.5 CHISQ.TEST——返回独立性检验值 328 8.6.6 F.DIST.RT——返回F概率分布 329 8.6.7 F.DIST——返回F概率分布 330 8.6.8 F.INV.RT——返回F概率分布的反函数值 330 8.6.9 F.INV——返回F概率分布的反函数值 331 8.6.10 T.DIST.2T——返回t分布的双尾概率 332 8.6.11 T.DIST.RT——返回t分布的右尾概率 333 8.6.12 T.DIST——返回t分布 333 8.6.13 T.INV.2T——返回t分布的双尾反函数值 334 8.6.14 T.INV——返回t分布的左尾反函数值 335 8.6.15 F.TEST——返回F检验的结果 335 8.6.16 T.TEST——返回与t检验相关的概率 336 8.6.17 Z.TEST——返回z检验的单尾概率 337 8.7 统计协方差、相关系数与回归 338 8.7.1 COVARIANCE.P——计算总体协方差,即成对偏差乘积的平均值 338 8.7.2 COVARIANCE.S——计算样本协方差,即成对偏差乘积的平均值 339 8.7.3 CORREL——返回两个数据集之间的相关系数 340 8.7.4 FISHER——返回Fisher变换值 340 8.7.5 FISHERINV——返回Fisher变换的反函数值 341 8.7.6 PEARSON——返回皮尔生乘积矩相关系数 342 8.7.7 RSQ——返回皮尔生乘积矩相关系数的平方 343 8.7.8 FORECAST——根据现有的数据计算或预测未来值 344 8.7.9 GROWTH——根据现有的数据计算或预测指数增长值 345 8.7.10 TREND——计算一条线性回归线的值 346 8.7.11 LINEST——返回线性回归线的参数 347 8.7.12 LOGEST——返回指数回归线的参数 348 8.7.13 SLOPE——返回线性回归线的斜率 349 8.7.14 INTERCEPT——返回线性回归线的截距 350 8.7.15 STEYX——返回通过线性回归法预测每个x的y值时所产生的标准误差 351 第9章 财务函数 352 9.1 了解货币的时间价值 354 9.2 计算本金和利息 355 9.2.1 PMT——计算贷款的每期付款额 355 9.2.2 IPMT——计算贷款在给定期间内支付的利息 356 9.2.3 PPMT——计算贷款在给定期间内偿还的本金 357 9.2.4 ISPMT——计算特定投资期内支付的利息 358 9.2.5 CUMIPMT——计算两个付款期之间累积支付的利息 358 9.2.6 CUMPRINC——计算两个付款期之间累积支付的本金 360 9.2.7 EFFECT——将名义年利率转换为实际年利率 361 9.2.8 NOMINAL——将实际年利率转换为名义年利率 362 9.2.9 RATE——计算年金的各期利率 362 9.3 计算投资预算 363 9.3.1 FV——计算一笔投资的未来值 363 9.3.2 FVSCHEDULE——使用一系列复利率计算初始本金的未来值 364 9.3.3 NPER——计算投资的期数 365 9.3.4 PDURATION——计算投资到达指定值所需的期数 366 9.3.5 PV——计算投资的现值 367 9.3.6 NPV——基于一系列定期的现金流和贴现率计算投资的净现值 367 9.3.7 XNPV——计算一组未必定期发生的现金流的净现值 368 9.3.8 RRI——计算某项投资增长的等效利率 369 9.4 计算收益率 370 9.4.1 IRR——计算一系列现金流的内部收益率 370 9.4.2 MIRR——计算正负现金流在不同利率下支付的内部收益率 371 9.4.3 XIRR——计算一组未必定期发生的现金流的内部收益率 372 9.5 计算折旧值 373 9.5.1 AMORDEGRC——根据资产的耐用年限,计算每个结算期间的折旧值 373 9.5.2 AMORLINC——计算每个结算期间的折旧值 374 9.5.3 DB——使用固定余额递减法,计算一笔资产在给定期间内的折旧值 375 9.5.4 DDB——使用双倍余额递减法或其他指定方法,计算一笔资产在给定期间内的折旧值 376 9.5.5 VDB——使用余额递减法,计算一笔资产在给定期间或部分期间内的折旧值 377 9.5.6 SYD——计算某项资产按年限总和折旧法计算的指定期间的折旧值 378 9.5.7 SLN——计算某项资产在一个期间内的线性折旧值 379 9.6 计算证券与国库券 379 9.6.1 ACCRINT——计算定期支付利息的有价证券的应计利息 379 9.6.2 ACCRINTM——计算在到期日支付利息的有价证券的应计利息 380 9.6.3 COUPDAYBS——计算当前付息期内截止到成交日的天数 382 9.6.4 COUPDAYS——计算成交日所在的付息期的天数 383 9.6.5 COUPDAYSNC——计算从成交日到下一个付息日之间的天数 384 9.6.6 COUPNCD——计算成交日之后的下一个付息日 385 9.6.7 COUPNUM——计算成交日和到期日之间的应付利息次数 386 9.6.8 COUPPCD——计算成交日之前的上一付息日 387 9.6.9 DISC——计算有价证券的贴现率 389 9.6.10 DURATION——计算定期支付利息的有价证券的修正期限 390 9.6.11 PRICE——计算定期付息的面值¥100的有价证券的价格 391 9.6.12 PRICEDISC——计算折价发行的面值¥100的有价证券的价格 392 9.6.13 PRICEMAT——计算到期付息的面值¥100的有价证券的价格 393 9.6.14 ODDFPRICE——计算首期付息日不固定的面值¥100的有价证券价格 395 9.6.15 ODDFYIELD——计算首期付息日不固定的有价证券的收益率 396 9.6.16 ODDLPRICE——计算末期付息日不固定的面值¥100的有价证券价格 397 9.6.17 ODDLYIELD——计算末期付息日不固定的有价证券的收益率 399 9.6.18 MDURATION——计算假设面值为¥100的有价证券的Macauley修正期限 400 9.6.19 INTRATE——计算一次性付息证券的利率 401 9.6.20 RECEIVED——计算一次性付息的有价证券到期收回的金额 403 9.6.21 TBILLEQ——计算国库券的等价债券收益 404 9.6.22 TBILLPRICE——计算面值¥100的国库券的价格 405 9.6.23 TBILLYIELD——计算国库券的收益率 406 9.6.24 YIELD——计算定期支付利息的有价证券的收益率 406 9.6.25 YIELDDISC——计算折价发行的有价证券的年收益率 408 9.6.26 YIELDMAT——计算到期付息的有价证券的年收益率 409 9.7 转换美元价格的格式 410 9.7.1 DOLLARDE——将以分数表示的美元价格转换为以小数表示的美元价格 410 9.7.2 DOLLARFR——将以小数表示的美元价格转换为以分数表示的美元价格 411 第10章 工程函数 412 10.1 比较数据函数 414 10.1.1 DELTA——测试两个值是否相等 414 10.1.2 GESTEP——测试某个值是否大于等于阈值 415 10.2 转换数制 416 10.2.1 BIN2OCT——将二进制数转换为八进制数 416 10.2.2 BIN2DEC——将二进制数转换为十进制数 417 10.2.3 BIN2HEX——将二进制数转换为十六进制数 418 10.2.4 OCT2BIN——将八进制数转换为二进制数 419 10.2.5 OCT2DEC——将八进制数转换为十进制数 420 10.2.6 OCT2HEX——将八进制数转换为十六进制数 420 10.2.7 DEC2BIN——将十进制数转换为二进制数 421 10.2.8 DEC2OCT——将十进制数转换为八进制数 422 10.2.9 DEC2HEX——将十进制数转换为十六进制数 423 10.2.10 HEX2BIN——将十六进制数转换为二进制数 424 10.2.11 HEX2OCT——将十六进制数转换为八进制数 425 10.2.12 HEX2DEC——将十六进制数转换为十进制数 426 10.3 计算复数 427 10.3.1 COMPLEX——将实系数和虚系数转换为复数 427 10.3.2 IMREAL——返回复数的实系数 427 10.3.3 IMAGINARY——返回复数的虚系数 428 10.3.4 IMCONJUGATE——返回复数的共轭复数 429 10.3.5 IMABS——计算复数的绝对值(模数) 429 10.3.6 IMPOWER——计算复数的整数幂 430 10.3.7 IMSQRT——计算复数的平方根 431 10.3.8 IMARGUMENT——返回以弧度表示的角 432 10.3.9 IMEXP——计算复数的指数 432 10.3.10 IMLN——计算复数的自然对数 433 10.3.11 IMLOG10——计算复数以10为底的对数 433 10.3.12 IMLOG2——计算复数以2为底的对数 434 10.3.13 IMSUM——计算多个复数的总和 435 10.3.14 IMSUB——计算两个复数的差 435 10.3.15 IMPRODUCT——计算多个复数的乘积 436 10.3.16 IMDIV——计算两个复数的商 437 10.3.17 IMSIN——计算复数的正弦值 437 10.3.18 IMSINH——计算复数的双曲正弦值 438 10.3.19 IMCOS——计算复数的余弦值 439 10.3.20 IMCOSH——计算复数的双曲余弦值 440 10.3.21 IMTAN——计算复数的正切值 440 10.3.22 IMSECH——计算复数的双曲正切值 441 10.3.23 IMCOT——计算复数的余切值 442 10.3.24 IMSEC——计算复数的正割值 442 10.3.25 IMCSC——计算复数的余割值 443 10.3.26 IMCSCH——计算复数的双曲余割值 444 10.4 其他工程函数 445 10.4.1 CONVERT——将数字从一种度量系统转换为另一种度量系统 445 10.4.2 BESSELJ——返回贝赛尔函数Jn(x) 446 10.4.3 BESSELY——返回贝赛尔函数Yn(x) 447 10.4.4 BESSELI——返回修正的贝赛尔函数In(x) 448 10.4.5 BESSELK——返回修正的贝赛尔函数Kn(x) 449 10.4.6 ERF——返回误差函数 450 10.4.7 ERF.PRECISE——返回误差函数 450 10.4.8 ERFC——返回补余误差函数 451 10.4.9 ERFC.PRECISE——返回补余误差函数 451 10.4.10 BITAND——返回两个数按位“与”的结果 452 10.4.11 BITOR——返回两个数按位“或”的结果 453 10.4.12 BITXOR——返回两个数按位“异或”的结果 454 10.4.13 BITLSHIFT——返回向左移动指定位数后的值 455 10.4.14 BITRSHIFT——返回向右移动指定位数后的值 456 第11章 数据库函数 458 11.1 计算数据库中的数据 458 11.1.1 DPRODUCT——计算满足条件的数字的乘积 458 11.1.2 DSUM——计算满足条件的数字的总和 460 11.2 对数据库中的数据进行常规统计 461 11.2.1 DAVERAGE——计算满足条件的数值的平均值 461 11.2.2 DCOUNT——计算满足条件的包含数字的单元格的个数 463 11.2.3 DCOUNTA——计算满足条件的非空单元格的个数 464 11.2.4 DGET——返回符合条件的单个值 465 11.2.5 DMAX——返回满足条件的列表中的最大值 467 11.2.6 DMIN——返回满足条件的列表中的最小值 468 11.3 对数据库中的数据进行散布度统计 469 11.3.1 DSTDEV——返回满足条件的数字作为一个样本估算出的样本标准偏差 469 11.3.2 DSTDEVP——返回满足条件的数字作为样本总体计算出的总体标准偏差 471 11.3.3 DVAR——返回满足条件的数字作为一个样本估算出的样本总体方差 472 11.3.4 DVARP——返回满足条件的数字作为样本总体计算出的总体方差 473 第12章 Web函数与宏表函数 475 12.1 Web函数 475 12.1.1 ENCODEURL——将文本转换为URL编码 475 12.1.2 WEBSERVICE——从Web服务中获取网络数据 476 12.1.3 FILTERXML——在XML结构化内容中获取指定路径下的信息 476 12.2 宏表函数 477 12.2.1 GET.WORKBOOK——返回工作簿的相关信息 477 12.2.2 GET.CELL——返回单元格的相关信息 478 12.2.3 EVALUATE——计算包含文本的表达式的值 480 第13章 在条件格式中使用公式 482 13.1 条件格式简介 482 13.2 在条件格式中公式的使用 483 13.2.1 创建基于公式的条件格式的原则 483 13.2.2 条件格式公式示例 485 第14章 在数据验证中使用公式 489 14.1 数据验证简介 489 14.2 在数据验证中公式的使用 491 14.2.1 创建基于公式的数据验证的原则 491 14.2.2 数据验证公式示例 491 第15章 在图表中使用公式 496 15.1 图表简介 496 15.1.1 图表类型 496 15.1.2 图表元素 501 15.1.3 创建图表 502 15.1.4 图表在工作簿中的位置 504 15.2 使用公式与控件创建动态图表 505 15.2.1 在图表中使用公式 505 15.2.2 在图表中使用控件 505 15.2.3 了解数据系列的SERIES公式 506 15.2.4 动态图表示例 507 附录1 Excel快捷键 518 1.工作簿基本操作的快捷键 518 2.在工作表中移动和选择的快捷键 518 3.在工作表中编辑的快捷键 519 4.在工作表中设置格式的快捷键 521 附录2 Excel函数速查表 522 1.逻辑函数 522 2.信息函数 522 3.文本函数 523 4.数学和三角函数 523 5.统计函数 526 6.查找和引用函数 529 7.日期和时间函数 529 8.财务函数 530 9.工程函数 532 10.数据库函数 533 11.多维数据集函数 534 12.Web函数 534 13.加载宏和自动化函数 534 14.兼容性函数 534
习 题 答 案 习题一答案 一、选择题 1. 软件的主要特性是(A B C)。 A) 无形 B) 高成本 C) 包括程序和文档   D) 可独立构成计算机系统 2. 软件工程三要素是(C D)。 A) 技术、方法和工具  B) 方法、工具和过程  C) 方法、对象和类  D) 过程、模型、方法 3. 包含风险分析的软件工程模型是(A)。 A) 螺旋模型 B) 瀑布模型 C) 增量模型 D) 喷泉模型 4. 软件工程的主要目标是(C)。 A) 软件需求  B) 软件设计  C) 风险分析  D) 软件实 现 5. 下列属于面向对象开发方法的是(A B C D)。 A) Booch   B) UML   C) Coad   D) OMT 6. 软件危机的主要表现是(B D)。 A) 软件成本太高 B) 软件产品的质量低劣 C) 软件开发人员明显不足 D) 软件生产率低下 7. 软件开发方法的主要工作模型有(A B C) A) 螺旋模型 B) 循环模型 C) 瀑布模型 D) 专家模型 8. 软件工程的目标有(A B C)。 A) 易于维护 B) 低的开发成本 C) 高性能 D) 短的开发期 9. 软件工程学的目的和意义是( )。 A) 应用科学的方法和工程化的规范管理来指导软件开发 B) 克服软件危机 C) 作好软件开发的培训工作 D) 以较低的成本开发出高质量的软件 二、 判断题 1. 软件就是程序,编写软件就是编写程序。(×) 2. 瀑布模型的最大优点是将软件开发的各个阶段划分得十分清晰。(×) 3. 结构化方法的工作模型是使用螺旋模型进行开发。(×) 4. 结构化方法和JSP方法都不适合于大型软件的开发。(√) 5. 原型化开发方法包括生成原型和实现原型两个步骤。(×) 6. 面向对象的开发方法包括面向对象的分析、面向对象的设计和面向对象的程序设计。( √) 7. 软件危机的主要表现是软件的需求量迅速增加,软件价格上升。(×) 8. 软件工具的作用是为了延长软件产品的寿命。(×) 9. 软件工程过程应该以软件设计为中心,关键是编写程序。(×) 10. RCP法与RSP法的主要区别是前者采用循环渐进的开发方式,原型将成为最终的产品,而后者将被废弃。(√) 三、简答题 1. 软件产品的特性是什么? 答: ● 软件是一种逻辑产品,具有无形性;  ● 软件产品的生产主要是研制;  ● 软件不存在磨损和老化问题,但存在退化问题;  ● 软件产品的生产主要是脑力劳动;  ● 软件产品的成本非常昂贵,其开发方式目前尚未完全摆脱手工生产方式; ● 软件具有“复杂性”,其开发和运行常受到计算机系统的限制。 2. 软件发展有几个阶段?各有何特征? 答: ① 程序设计阶段。    硬件特征:价格贵、存储容量小、运行可靠性差。    软件特征:只有程序、程序设计概念,不重视程序设计方法。   ② 程序系统阶段。    硬件特征:速度、容量及工作可靠性有明显提高,价格降低,销售有爆炸性增长 。    软件特征:程序员数量猛增,开发人员素质低。   ③ 软件工程阶段。    硬件特征:向超高速、大容量、微型化及网络化方向发展。    软件特征:开发技术有很大进步,但未获得突破性进展,软件价格不断上升,未完全摆脱软件危机。 3. 什么是软件危机?其产生的原因是什么? 答:“软件危机”(Software Crisis)的出现是由于软件的规模越来越大,复杂度不断增 加,软件需求量增大。而软件开发过程是一种高密集度的脑力劳动,软件开发的模式及技术 不能适应软件发展的需要。致使大量质量低劣的软件涌向市场,有的花费大量人力、财力, 而在开发过程中就夭折。软件危机主要表现在两个方面: (1) 软件产品质量低劣,甚至开发过程就夭折。 (2) 软件生产率低,不能满足需要。 4. 什么是软件生存周期模型?它有哪些主要模型? 答:软件生存周期模型是描述软件开发过程中各种活动如何执行的模型。 主要模型包括:瀑布模型、增量模型、螺旋模型、喷泉模型、变换模型和基于知识的模型。 5. 有哪些主要的软件开发方法? 答:主要的软件开发方法有:结构化开发方法、Jackson(JSP、JSD)方法、原型化开发方 法、维也纳开发方法(VDM)和面向对象的开发方法。 6. 软件生命期各阶段的任务是什么? 答:软件生命期瀑布模型分为六个阶段: ● 可行性研究与计划(确定系统的目标和规模,分析项目的可行性); ● 需求分析与规格说明(明确系统的规格和要求); ● 设计(包括概要设计和详细设计,将系统分解为模块); ● 编程(用程序语言实现每个模块,简单容易); ● 测试(发现并改正错误,分为模块测试、集成测试和系统联调三级); ● 运行维护(扩充功能、纠错等)。 习题二答案 一、 选择题 1. 需求分析的主要目的是(B C)。 A) 系统开发的具体方案 B) 进一步确定用户的需求 C) 解决系统是“做什么的问题” D) 解决系统是“如何做的问题” 2. 需求分析的主要方法有(C D)。 A) 形式化分析方法 B) PAD图描述 C) 结构化分析(SA)方法 D) OOA法 3. 面向对象的分析方法主要是建立三类模型,即(D)。 A) 系统模型、ER模型、应用模型 B) 对象模型、动态模型、应用模型 C) E-R模型、对象模型、功能模型 D) 对象模型、动态模型、功能模型 4. SA法的主要描述手段有(B)。 A) 系统流程图和模块图 B) DFD图、数据词典、加工说明 C) 软件结构图、加工说明 D) 功能结构图、加工说明 5. 画分层DFD图的基本原则有(A C D)。 A) 数据守恒原则 B) 分解的可靠性原则 C) 子、父图平衡的原则 D) 数据流封闭的原则 6. 在E-R模型中,包含以下基本成分(C)。 A) 数据、对象、实体 B) 控制、联系、对象 C) 实体、联系、属性 D) 实体、属性、联系 7. 画DFD图的主要目的是(A D)。 A) 作为需求分析阶段用户与开发者之间交流信息的工具 B) 对系统的数据结构进行描述 C) 对目标系统的层次结构进行描述 D) 作为分析和设计的工具 8. 数据字典是数据流图中所有元素的定义的集合,一般由以下四类条目组成(C)。 A) 数据说明条目、控制流条目、加工条目、数据存储条目 B) 数据流条目、数据项条目、文件条目、加工条目 C) 数据源条目、数据流条目、数据处理条目、数据文件条目 D) 数据流条目、数据文件条目、数据池条目、加工条目 9. 在需求分析阶段主要采用图形工具来描述的原因是(B C)。 A) 图形的信息量大,便于描述规模大的软件系统 B) 图形工具能够极好地概括描述一个系统的信息,比文字叙述能够更好地表达重 要的细节 C) 图形能够更加直观地描述目标系统,便于用户理解和交流,有利于开发者与用 户之间达成一致的需求 D) 图形比文字描述简单、形象 二、 判断题 1. 在进行了可行性分析后,需求分析就只需要解决目标系统的设计方案。(×) 2. SA法是面向数据流,建立在数据封闭原则上的需求分析方法。(√) 3. HIPO法既是需求分析方法,又是软件设计方法。(√) 4. 在面向对象的需求分析方法中,建立动态模型是最主要的任务。(×) 5. 加工小说明是对系统流程图中的加工进行说明。(×) 6. 判定表的优点是容易转换为计算机实现,缺点是不能够描述组合条件。(×) 7. 需求分析的主要方法有SD法、OOA法及HIPO法等。(×) 8. 分层的DFD图可以用于可行性分析阶段,描述系统的物理结构。(×) 9. 信息建模方法是从数据的角度来建立信息模型的,最常用的描述信息模型的方法是E-R 图。(√)  10. 用于需求分析的软件工具,应该能够保证需求的正确性,即验证需求的一致性、完整性、现实性和有效性。(√) 三、 问答题 1. 什么是需求分析?需求分析阶段的基本任务是什么? 答: 需求分析是当前软件工程中的关键问题,需求分析阶段的任务是:在可行性分析的基础上,进一步了解、确定用户需求。准确地回答 “系统必须做什么?” 的问题。获得需求规格说 明书。还涉及到软件系统的目标、软件系统提供的服务、软件系统的约束和软件系统运行的环境。它还涉及到这些因素和系统的精确规格说明,以及系统进化之间的关系。 需求分析的基本任务包括: (1) 抽取需求 分析现行系统存在需要解决的问题。获取足够多的问题领域的知识,需求抽取的方法一般有问卷法、面谈法、数据采集法、用例法、情景实例法以及基于目标的方法等;还有知识工程方法,例如,场记分析法、卡片分类法、分类表格技术和基于模型的知识获取等 。 (2) 模拟和分析需求 需求分析和模拟又包含三个层次的工作。首先是需求建模。需求模型的表现形式有自然语言、半形式化(如图、表、结构化英语等)和形式化表示等三种。需求概念模型的要求包括实现的独立性:不模拟数据的表示和内部组织等;需求模拟技术又分为企业模拟、功能需求模拟和非功能需求模拟等。 (3) 传递需求 传递需求的主要任务是书写软件需求规格说明。 (4) 认可需求 就是对需求规格说明达成一致,其主要任务是冲突求解,包括定义冲突和冲突求解两方面。常用的冲突求解方法有:协商、竞争、仲裁、强制、教育等,其中有些只能用人的因素去控制。 (5) 进化需求 客户的需要总是不断(连续)地增长,但是一般的软件开发又总是落后于客户需求的增长,如何管理需求的进化(变化)就成为软件进化的首要问题。对于传统的变化管理过程来说,其基本成分包括软件配置、软件基线和变化审查小组。当前的发展是软件家族法 ,即产品线方法。多视点方法也是管理需求变化的一种新方法,它可以用于管理不一致性, 并进行关于变化的推理。 2. M公司的软件产品以开发实验型的新软件为主。用瀑布模型进行软件开发已经有近十年了,并取得了一些成功。若你作为一名管理员刚加入M公司,你认为快速原型法对公司的软件开发更加优越,请向公司副总裁写一份报告阐明你的理由,切记:副总裁不喜欢报告长度 超过一页(B5)。 参考答案提示: 应先简述瀑布模型的缺点,它已不适宜开发实验型的软件。根据快速原型法的特点,说明它特别适合于开发探索型、实验型的软件。 3. 如何画分层数据流图? 答: 总的原则是:至顶而下,逐层分解(画分层数据流图)。 比较复杂的系统不能画在一张纸上,逐层分解的画法可以控制每一层的复杂度。 顶层:将整个系统作为一个加工,描述系统边界(输入与输出)。 中间层:表示某个加工分解为一组子加工,其中的子加工还需进一步分解。 底层:由不再进行分解的基本加工组成。 4. 加工小说明有哪些描述方法? 答: ● 结构化语言:介于自然语言和形式语言(如谓词逻辑)之间。 ● 结构化英语:通常由外层和内层结构组成。 ● 汉语的情况:精确、简明扼要、文体可以灵活。 ● 判定表:适用于表述比较复杂的加工逻辑,如具有多项选择条件的操作。 ● 判定树:本质上与判定表相同,图形表示更易于理解。 5. 考察下图中子图、父图的平衡。 图1 图2 参考答案: 图1中子图与父图不平衡。子图是父图中加工2的分解,加工2 有输入数据流M和N,输出数据流T,而子图则只有一个输入数据N,却有两个输出数据流T与S。 图2中子图是父图中加工3的分解,虽然表面上加工3只有一个输入数据流“订货单”,而子图却有三个输入数据流,但是如果“订货单”是由“客户”、“账号”和“数量”三部分组成,即有如下数据条目,订货单=客户+账号+数量(2.2.5数据词典),则子、父图平衡。 6. 画出银行取款过程的DFD图。问题描述为:储户用存折取款,首先填写取款单,根据“ 账卡”中的信息检验取款单与存折,如有问题,将问题反馈给储户,否则,登录“储户存款 数据库”,修改相应数据,并更新“账卡”,同时发出付款通知,出纳向储户付款。 参考答案: 7. 常用的软件需求分析方法有哪些? 答: 结构化分析方法(SA)、功能分解法、信息建模法、面向对象的分析方法(OOA)。 习题三答案 一、 选择题 1. 模块的基本特征是(A C)。 A) 外部特征(输入/输出、功能) B) 内部特征(输入/输出、功能) C) 内部特征(局部数据、代码) D) 外部特征(局部数据、代码 ) 2. SD方法的设计总则是(C D)。 A) 程序简洁、操作方便 B) 结构清晰、合理 C) 模块内聚性强 D) 模块之间耦合度低 3. 软件设计的主要任务是(A B D)。 A) 将分析阶段获得的需求说明转换为计算机中可实现的系统 B) 完成系统的数据结构和程序结构设计 C) 完成模块的编码和测试 D) 对模块内部的过程进行设计 4. 设计阶段应达到的目标有(A D)。 A) 提高可靠性和可维护性 B) 提高应用范围 C) 结构清晰 D) 提高可理解性和效率 5. 从工程管理的角度来看,软件设计分两步完成(D)。 A) ①系统分析②模块设计 B) ①详细设计②总体设 计 C) ①模块设计②详细设计 D) ①总体设计②详细设 计 6. 模块独立性准则由以下定性指标来衡量(BD)。 A) 分解度    B) 耦合度    C) 屏蔽性    D) 内聚性 7. 用户界面设计的任务包括(A B C)。 A) 确定用户界面类型 B) 建立任务模型 C) 建立用户模型 D) 建立功能模型 8. 程序设计语言可以分为(B C D)。 A) 面向过程的语言    B) 机器语言 C) 高级语言    D) 汇编语言  9. 程序效率包括(A C D)几个方面的内容。 A) 代码效率     B) 运行效率    C) 存储效率     D) I/O效率 10. SP方法中的基本控制结构有(A B C)。 A) 顺序结构 B) 选择结构 C) 重复结构 D) GOTO结构 11. 内部文档可用注释语言书写,注释语言分为(A B C D)。 A) 序言性注释 B) 描述性注释 C) 功能性注释 D) 状态性注释 12. 为使程序中数据说明更易于理解和维护,必须遵循以下原则(A B C) 。 A) 数据说明的次序应当规范化 B) 一个语句说明多个变量时,各变量名按字母顺序排列 C) 对于复杂的数据结构,要加注释,说明在程序实现时的特点 D) 定义变量名应按字母顺序排列 13. 源程序的效率与(D)阶段确定的算法的效率直接有关。 A) 概要设计 B) 总体设计 C) 单元设计 D) 详细设计 14. 在详细设计翻译转换成源程序代码后,算法效率反映为对程序的哪几个方面的要求 (C D)。 A) 读写速度 B) 代码长度 C) 存储容量 D) 执行速度 15. 提高程序效率的根本途径在于(B C)。 A) 编程时对程序语句进行调整 B) 选择良好的设计方法 C) 使程序最大限度的简洁 D) 选择良好的数据结构与算法 二、判断题 1. 划分模块可以降低软件的复杂度和工作量,所以应该将模块分得越小越好。 (×) 2. 在网状结构中任何两个模块都是平等的,没有从属关系,所以在软件开发过程中常常被使用。(×) 3. 信息隐蔽原则有利于提高模块的内聚性。(√) 4. 中心变换型的DFD图可看成是对输入数据进行转换而得到输出数据的处理,因此可以使 用事务分析技术得到初始的模块结构图。(×) 5. SD法是一种面向数据结构的设计方法,强调程序结构与问题结构相对应。 (×) 6. 所谓结构冲突,是指输入数据与输出数据之间很少或没有结构上的对应关系。通常解决 的办法是:构造一个或者多个中间结构,在输入和输出结构之间进行转换。(√) 7. 当模块的控制范围是其作用范围的子集时,模块之间的耦合度较低。(×) 8. JACKSON方法是以数据流、数据封闭性准则逐层分解的。(×) 9. 程序设计语言的工程特性包括:可移植性、可重用性、可维护性、局部性和顺序性。(×) 10. 项目应用领域是选择语言的关键因素。(√) 11. FORTRAN、Pascal、C语言、PL/1和汇编语言都是科学工程计算可选用的语言。(×) 12. 要用快速原型法开发软件,应选用4GL语言。(√) 13. 提高程序效率的根本途径是选择良好的设计方法、数据结构与算法。(×) 14. 良好的程序设计风格简单说就是高的编程技巧。(√) 三、简答题 1. 模块内联系和模块间联系有哪些种类? 答:块间联系的各种类型的划分,从以下3方面考虑: ● 按块间联系的方式(可分为直接引用与过程调用); ● 按块间共用信息的作用(可分为数据型、控制型与混合型); ● 按块间共用的信息数量多少(信息多联系紧密)。 (1) 块间联系的类型,按照耦合度由大到小分为: 内容型:直接引用另一模块的内部信息; 公共型:两个模块引用共同的全程数据区; 控制型:模块间传送的信息用于控制模块的内部逻辑; 复合型:模块间传送复合的数据结构; 数据型:模块间传送单个数据项。 (2) 块内联系的类型,按照内聚性从小到大分为: 偶然型:模块内部没有必然联系; 逻辑型:逻辑上相似的功能放进一个模块; 瞬时型:将同时执行的语句放在一个模块; 通信型:模块中的各部分引用共同的数据; 顺序型:模块中一部分的输出是另一部分的收入; 功能型: 模块中刚好包含了完成一个基本任务所必需的成分。 2. 分析以下DFD图,说明属于哪种类型的DFD图,并按照相应的变换将其转换为初始的模块 结构图。 参考答案:(略) 3. 下图是修改文件记录的DFD图,请确定其主加工。 解:主加工为:账号、修改、写记录。 4. 按照“降低块间联系,提高块内联系”的设计总则对模块进行修改,具体从哪些方面进 行改进? 解: (1) 尽可能建立功能模块; (2) 消除重复功能; (3) 模块的作用范围与控制范围,即当作用范围为控制范围的子集时,才能获得较低的块间 联系; (4) 模块的大小适当; (5) 模块的扇入扇出数不宜太多。 5. 根据模块的作用范围与控制范围的原则,判定a、b两图的正确性。 解:显然,图a不满足作用范围应与控制范围的原则,模块F的作用范围不在控制范围之内。 图b的模块设计合理。 6. 图a中,模块G为判定,判断涉及到模块B、F、G,请指出设计中的错误,再根据改进模 块图的基本原则,画出1~2个改进方案(不改变模块G的判断关系),并说明是按照哪条基本 原则进行改进的。 解:图b为一个改进方案,将模块G的位置提高,使其作用范围为控制范围的子集,减少模块 之间的联系。 7. 编码阶段的主要任务是什,应交付的结果是什么? 答:编码阶段的主要任务是为每个模块编写程序。即是:将详细设计的结果转换为用某种计 算机语言写的程序——源程序代码。编码阶段应交付的结果是带有“程序内部文档”的、不 再含有语法错误的程序。 8. SP法的自顶向下,逐步求精方法的优点有哪些? 答:此法符合人们解决复杂问题的普遍规律,可提高软件开发的成功率和生产率;而且用先 全局后局部、先整体后细节、先抽象后具体的逐步求精过程,开发出来的程序具有清晰的层 次结构,因此程序容易阅读和理解。这样,程序自顶向下,逐步细化,分解成一个树型结构 。 因此,在同一层次的节点上做细化工作,相互之间没有联系,它们之间的细化工作相互独立 ;在任何一步发生错误,一般只影响它下层的节点,同一层其他节点不受影响;在以后的测试中,也可以先独立地一个节点一个节点地做,最后再集成。这样,程序清晰和模块化,使 得在修改和重新设计一个软件时,可复用的代码量最大。 9. 为了使程序具有良好的设计风格,应注意哪些方面的问题? 答:(1) 标识符应按意取名。 标识符即符号名,包括:模块名、常量名、标号名、子程序名、数据区名、缓冲区名等。 这些名字应能反映它所代表的实际东西,应有一定实际意义,使其能够见名知意,有助于对 程序功能的理解。 (2) 程序应加注释,它分为两类:序言性注释和功能性注释。 序言性注释应置于每个模块的起始部分,主要内容有:①说明每个模块的用途,功能;②说明模块的接口即调用格式、参数描述及从属模块的清单;③数据描述;④开发历史 。 功能性注释是嵌在源程序体中的,用于说明其后的程序段或语句的功能以及数据的状态;也就是解释下面要“做什么”,或是执行下面的语句会发生什么情况;而不是解释下面“怎么做”,因为怎么做常常是与程序重复的,且对读者理解程序没有什么帮助。 10. 样评价程序的执行效率?它与程序清晰性的关系是怎样的? 答:许多程序员往往片面追求效率,其实程序系统的成本不仅包括运行所需的机时,同时还应把程序员及操作员所花费的人力考虑进去。在编程时为追求效率而损害可读性或可靠性,会给以后的维护工作带来困难,所以从整体上看来是不值得的。 此外,还应该认识到,提高程序效率的根本途径在于:选择良好的设计方法、良好的数据结构与算法,而不是靠编程时对程序语句进行调整。 (1) 追求建立在不损害程序可读性或可靠性基础上,要先使程序正确、清晰,再提高程序 效率。 (2) 不能因为贪图效率上的小利,而破坏程序的清晰性。 (3) 让编译程序去作简单的优化。 (4) 提高程序效率的根本途径在于:选择良好的设计方法和良好的数据结构与算法,而不是靠编程时对程序语句做调整。 11. 假定:需要编一个求解一元二次方程根的子程序,加入到现有的子程序库中,供其他程序员使用。要求: (1) 为该子程序写一个序言性注释; (2) 用PASCAL语言或其他语言写出这个子程序(要把根的性质,如:实根、复根、降为一次方程等有区别地通知调用者),并加上描述性注释。 答案:(略) 习题四答案 一、选择题 1. 面向对象程序设计的基本机制(ABC)。 A) 继承 B) 消息 C) 方法 D) 结构 2. 下列属于面向对象的要素有(BCD)。 A) 分类性 B) 抽象 C) 共享 D) 封装 3. 下列选项中属于面向对象开发方法的有(ACD)。 A) Booch B) CAD C) Coad D) OMT 4. 下列属于Coad方法中面向对象的分析模型的层次有(AB)。 A) 主题层 B) 对象层 C) 应用层 D) 接口层 5. 一个类属性依其特征划分,其类型有(ABCD)。 A) 描述型 B) 定义型 C) 派生型 D) 参考型 6. 在进行面向对象分析时,所采用的模型有(ABD)。 A) 对象模型 B) 动态模型 C) 静态模型 D) 功能模型 7. 状态是对象属性的值的一种抽象,它的性质有(AB)。 A) 时间性 B) 持续性 C) 有序性 D) 有穷性 8. 数据流图中的处理必须用对象中的操作来实现常见的操作有(ABCD)。 A) 查询 B) 动作 C) 活动 D) 访问 9. 建立继承关系时所采用的方式有(AC)。 A) 自顶向下 B) 从内到外 C) 自底向上 D) 从复杂到简单 10. 对象是人们要研究的任何事物主要的对象类型有(ABCD)。 A) 有形实体 B) 作用 C) 事件 D) 性能说明 二、判断题 1. 面向对象的的方法是以类作为最基本的元素,它是分析问题解决问题的核心。(×) 2. 类是指具有相同或相似性质对象的抽象,对象是抽象的类,类的具体化就是对象。(√) 3. 继承性是父类和子类之间共享数据结构和消息的机制,这是类之间的一种关系(×)。 4. 多态性增强了软件的灵活性和重用性,允许用更为明确、易懂的方式去建立通用软件, 多态性和继承性相结合使软件具有更广泛的重用性和可扩充性。(×) 5. 面向对象分析,就是抽取和整理用户需求并建立问题域精确模型的过程。(√) 6. 面向对象的设计的主要目标是提高生产效率,提高质量和提高可维护性。(√) 7. 对象模型表示了静态的、结构化的系统数据性质,描述了系统的静态结构,它是从客观世界实体的对象关系角度来描述,表现了对象的相互关系。(√) 8. 面向对象的分析是用面向对象的方法对目标系统的问题空间进行理解、分析和反映。通过对象层次结构的组织确定解空间中应存在的对象和对象层次结构。(√) 9. 类的设计过程包括:确定类,确定关联类,确定属性,识别继承关系。(√) 10. 复用也叫重用或再用,面向对象技术中的“类”,是比较理想的可重用软构件。有三种重用方式:实例重用、继承重用、多态重用。(√) 11. 主题是一种关于模型的抽象机制,它是面向对象模型的概貌,也是关于某个模型要同时考虑和理解的内容,主题起一种控制作用。(√) 12. 面向对象的分析由对象、结构、继承性和基于消息的通信构成。(×) 13. 支持继承性是面向对象程序设计语言和传统程序设计语言在语言机制方面的根本区别。(√) 14. 面向对象的分析过程主要包括三项内容:理解、表达和验证。(√) 15. 面向对象的设计的主要目标是提高生产效率、提高质量和提高可维护性。(√) 三、 简答题 1. 与传统程序设计模式中的过程调用相比,消息传递机制有何本质区别? 答: (1) 消息传递必须给出信道的信息,通常要指出明显的接受方。 (2) 由于接受方是一通信实体,具有保持状态的能力,所以同一发送方在不同时刻向同一 接受方发送同样的信息,可因接受方的当前状态不同而得到不同的结果。 (3) 消息传递可以是异步的,发送方可以不必等待接受方返回信息就可以继续执行后面的操作,因而支持程序的并发和分布执行,而过程调用只能是同步的,本质上是串行的。 2. 阐述面向对象的特征,并做简要的解释。 答: (1) 对象惟一性。 每个对象都有自身惟一的标识,通过这种标识,可找到相应的对象。 (2) 分类性。 是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。 (3) 继承性。 是父类和子类之间共享数据结构和方法的机制,这是类之间的一种关系。 (4) 多态性。 是指相同的操作或函数,过程作用于多种类型的对象上,并获得不同的结果。 3. Coad方法主要由面向对象分析OOA和面向对象设计OOD。OOA方法分析过程和构造OOA概念模型的顺序由5个层次组成,请简述这5个层次。 答: (1) 发现类及对象。描述如何发现类及对象。从应用领域开始识别类及对象,形成整 个应用的基础,然后,据此分析系统的责任。 (2) 识别结构。该阶段分为两个步骤。第一,识别“一般-特殊”结构,该结构捕获了识别出的类的层次结构;第二,识别“整体-部分”结构,该结构用来表示一个对象如何成为另一个对象的一部分,以及多个对象如何组装成更大的对象。 (3) 定义主题。主题由一组类及对象组成,用于将类及对象模型划分为更大的单位,便于理解。 (4) 定义属性。其中包括定义类的实例(对象)之间的实例连接。 (5) 定义服务。其中包括定义对象之间的消息连接。 4. 面向对象程序设计有哪些优点? 解:开发时间短、效率高、可靠性高,所开发的程序更强壮。由于面向对象编程的可重用性 ,可以在应用程序中大量采用成熟的类库,从而缩短开发时间,这样程序更易于维护、 更新和升级。继承和封装使得应用程序的修改带来的影响更加局部 化。 5.比较面向对象方法与结构化方法的特点。 解:分析是问题抽象 (做什么),设计是问题求解 (怎么做),实现是问题的解 (结果)。任 何方法学对客观世界的抽象和求解过程都是如此。在问题抽象阶段,结构化方法面向过程, 按照数据变换的过程寻找问题的结点,对问题进行分解。因此,与面向对象方法强调的对象 模型不同,描述数据变换的功能模型是结构化方法的重点。如果问题世界的功能比数据更复 杂或者更重要,那么结构化方法仍然应是首选的方法学。如果数据结构复杂且变换不多, 那么如果以过程主导分析和设计,一旦有系统变更就会给下游开发带来极大混乱。 由于对过程的理解不同,面向过程的功能细分所分割出的功能模块有时会因人而异。而面向 对象的对象细分,从同一问题领域的对象出发,不同人得出相同结论的比率较高。 在设计上,结构化方法学产生自顶向下、结构清晰的系统结构。每个模块有可能保持较强的独立性,但它往往与数据库结构相独立,功能模块与数据库逻辑模式间没有映射关系,程序与数据结构很难封装在一起。如果数据结构复杂,则模块独立性很难保证。面向对象方法抽象的系统结构往往并不比结构化方法产生的系统结构简单,但它能映射到数据库结构中,很容易实现程序与数据结构的封装。 在软件工程基本原则中有一条“形式化原则”,即对问题世界的抽象结论应该以形式化语言 (图形语言、伪码语言等)表述出来。结构化方法可以用数据流图、系统结构图、数据辞典、状态转移图、实体关系图来进行系统逻辑模型的描述;而面向对象方法可以使用对象模型图、数据辞典、动态模型图、功能模型图。其中对象模型图近似系统结构图与实体关系图的结合,动态模型图类似状态迁移图,功能模型图类似数据流图。 6.当重要的对象被发现后,通过一组互相关联的模型详细表示类之间的关系和对象的行为,这些模型从四个不同的侧面表示了软件的体系结构、静态逻辑、动态逻辑、静态物理和动态物理。试描述一下这四种特性。 解:静态逻辑模型描述实例化(类成员关系)、关联、聚集(整体/部分)、和一般化(继承)等关系。这被称为对象模型。一般化关系表示属性和方法的继承关系。定义对象模 型的图形符号体系通常是从用于数据建模的实体关系图导出的。对设计十分重要的约束,如 基数(一对一、一对多、多对多),也在对象模型中表示。 动态逻辑模型描述对象之间的互相作用。互相作用通过一组协同的对象,对象之间消 息的有序的序列,参与对象的可见性定义,来定义系统运行时的行为。 静态物理模型通过模块描述代码的布局。动态物理模型描述软件的进程和线程体系结 构。 习题五答案 一、选择题 1. 下列不是模型元素的是(D)。 A) 关联 B) 聚合 C) 依赖 D) 笔记 2. UML具有扩展性,常见的扩展机制有(BCD)。 A) 修饰 B) 版类 C) 加标签值 D) 约束 3. UML语言支持的建模方式有(ABD)。 A) 静态建模 B) 动态建模 C) 模块化建模 D) 功能建模 4. 下列各种图可用于动态建模的有(ACD)。 A) 状态图 B) 类图 C) 序列图 D) 活动图 5. 下列属于状态的组成部分的有(AB)。 A) 名称 B) 活动 C) 条件 D) 事件 6. UML中包括的事件有(ABCD)。 A) 条件为真 B) 收到另一对象的信号 C) 收到操作调用 D) 时间表达式 7. 属性的可见性有(ABD)。 A) 公有的 B) 私有的 C) 私有保护的 D) 保护的 8. 用例之间的关系有(BCD)。 A) 友元 B) 扩展 C) 使用 D) 组合 9. 应用于通用化约束的方式有(ABCD)。 A) 完整 B) 不相交 C) 不完整 D) 覆盖 10. 消息的类型有(ABC)。 A) 同步 B) 异步 C) 简单 D) 复杂 二、 判断题 1. UML建模语言是由视图、图、模型元素和通用机制构成的层次关系来描述的。 (√) 2. UML是一种建模语言,是一种标准的表示,是一种方法。 (×) 3. 泳道是一种分组机制,它描述了状态图中对象所执行的活动。 (×) 4. 同步消息和异步消息的主要区别是:同步消息的发送对象在消息发送后,不必等待消息处理,可立即继续执行,而异步消息则发送对象必须等待接收对象完成消息处理后,才能继续执行。 (×) 5. 类图中的角色是用于描述该类在关联中所扮演的角色和职责的。 (√) 6. 类图用来表示系统中类和类与类之间的关系,它是对系统动态结构的描述。 (×) 7. 用例模型的基本组成部件是用例、角色和用例之间的联系。 (√)
面向对象编程的基础 要了解面向对象编程(OOP)的基本概念,需要理解 OOP 的三个主要概念,它们撑起 了整个 OOP 的框架。这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 类、消息、接口、及抽象等概念。 2.2.1 对象 现实世界中的对象具两个特征:状态和行为。例如:自行车有状态(传动装置、步度、 两个车轮和齿轮的数目等)和行为(刹车、加速、减速和换档等)。 其次,我们再来看看软件对象。软件对象是现实世界对象的模式化产物,他们也有状态 和行为。软件对象把状态用数据表示并存放在变量里,而行为则用方法实现。实际上,软件 对象还包括了数据结构和使用这些数据结构的代码。因此也可以说:软件对象是现实世界客 观事务的软件化模拟,是变量(数据数据结构)和相关方法(对数据操作和对象管理的程 序)的软件组合。 在面向对象的程序设计中,你可以用软件对象表示现实世界的对象,而这些软件对象和 现实世界对象是相对应的。例如:如果你正在建立一个帐户管理系统,那么你的对象就是帐 户、欠款、信用卡、月收入、贷款、交易等等。如果你设计一个电子实习交通工具系统,那 么你的对象就是汽车、摩托车、自行车等等。就自行车的软件对象而言,表示该对象的状态 和行为应为与变量和方法相对应。自行车的状态:数度是 10mp(每小时 10 米),步度是 90rpm (每分钟 90 转),当前传动装置是第 5 个齿轮。再面向对象的程序设计中,这些数据应放在 变量中。自行车的行为:刹车,改变步度和换档。在面向对象的程序设计中,这些行为用方 法实现。 在 OOP 技术中,对象充当了一个很重要的角色。对象的数据是组成对象的核心,而方法 则环绕这个核心并隐藏在对象之中。 2.2.2 封装 "封装"是 OOP 语言的优点之一。把一个对象的数据加以包装并置于其方法的保护之下 称为封装。所谓封装就是对数据的隐藏。封装实现了把数据和操作这些数据的代码包装成为 一个对象(即离散的部件),而数据和操作细节(方法)隐藏起来。如果增加某些限制,使 得对数据的访问可按照统一的方式进行,那些能比较容易地产生更为强壮的代码。 OOP 语言提出一种(或称为协议),以保证对数据进行统一的操作。通常的做法是:程 序和对象数据的交互作用通过一个公开的接口进行,而不直接进行操作。由于把数据封装在 对象中,所以,访问对象中的数据只有一种途径,那就是利用一个公开的接口。 实际上,封装在程序和数据之间设置了一道栅栏,它可以阻止一部分的设计错误,不至 于涉足应用程序其他部分的数据。 2.2.3 消息 一个单独的对象一般不十分有用,而作为一员出现在包含有许多其他对象的大程序或应 用程序之中,通过这些对象的相互作用,程序员可实现高层次的操作和更负责的功能。某此 对象通过向其他对象发送消息与其他对象进行交互作用和通信。 消息是以参数的形式传递给某方法的。一个消息通常由三部分组成: 1. 消息传送到对象的名称。 2. 要执行的方法的名称。 3. 方法需要的任意参数。 2.2.4 类 类是一个蓝图或样板,定义了某种类型的所有对象的变量和方法。 在 java 语言中,Java 程序的基本单位是类,也就是说:一个 Java 程序是由多个类组成 的。定义一个类与定义一个数据类型是有区别的。在程序设计语言中,把定义数据类型的能 力作为一种很重要的能力来对待。在面向对象的语言中,类的功能更强大,这是因为类不仅 含有定义数据类型的功能,而且还包含了对方法的定义。 对象实际是类中的一个实例。生成实例的过程叫做把"一个对象实例化"。一个实例化 的对象实际上是由若干个实例变量和实例方法组成的。当你创建出一个类的实例时,系统将 为实例变量指定内存,然后你就可以利用实例方法去做某些事情。 2.2.5 继承 继承是指建立子类的能力。子类继承了父亲的特征和功能。类的层次结构类似于一棵数 的结构,也像一个家庭谱系。它显示了根和它的导出类之间的关系。 子类从它先辈类那里继承了代码和数据,这样,它就可以执行先辈类的功能和访问先辈 类的数据。一个纯面向对象程序设计的语言将具有严格的继承性。 通过对象、类,我们实现了封装,通过子类我们可以实现继承。例如,公共汽车、出租 车、货车等都是汽车,但它们是不同的汽车,除了具有汽车的共性外,它们还具有自己的特 点(如不同的操作方法,不同的用途等)。这时我们可以把它们作为汽车的子类来实现,它们 继承父类(汽车)的所有状态和行为,同时增加自己的状态和行为。通过父类和子类,我们实 现了类的的层次,可以从最一般的类开始,逐步特殊化,定义一系列的子类。同时,通过继 承也实现了代码的复用,使程序的复杂性线性地增长,而不是呈几何级数增长。 2.2.6 抽象 面向对象的程序设计系统鼓励充分利用"抽象"。在现实世界中,人们正是通过抽象来 理解复杂的事务。例如:人们并没有把汽车当作成百上千的零件组成来认识,而是把它当作 具有自己特定行为的对象。人们可以忽略发动机、液压传输、刹车系统等如何工作的细节, 而习惯于把汽车当作一个整体来认识。 包含通用对象类的库叫作类库。 2.2.7 多态型 面向对象程序的最后一个概念是多态性。凭借多态性,你可以创建一个新的对象,它具 有与基对象相同的功能,但是这些功能中的一个或多个是通过不同的方式完成的。例如:在 Java 中你可以凭借多态性,通过一个画圆的对象,来创建一个画椭圆或矩形的对象。不管是 画圆,画椭圆还是画矩形的方法,它们都有一个相同的方法名,但以不同的方式完成他们的 画圆的功能。 1.8 类和对象 1.8.1 类 类是组成 Java 程序的基本要素。它封装了一类对象的状态和方法,是这一类对象的 原型。定义一个类,实际上就是指定该类所包含的数据和对数据进行操作的代码。 类通过关键字 class 来定义,一般格式为: 【类说明修饰符】class 类名【extends 子句】【implements 子句】 type instance-varable1; type instance-varable2; type instance-varable3; the methodname1(parameter-list){method-body;} the methodname2(parameter-list){method-body;} the methodnameN (parameter-list){method-body;} 下面将类定义格式的项目说明如下: (1) class 是类说明关键字。 (2) 类名是由程序员自己定义的 Java 标识符,每个类说明必须有 class 和类名。 (3) 类说明修饰符包括:  abstract 说明一个类为抽象类,抽象类是指不能直接实例化对象的类。  final 说明一个类为最终类,即改类不能再有子类。  public 说明类为公共类,该类可以被当前包以外的类和对象使用。  private 说明类为私有类。 (4) extends 子句用于说明类的直接超类。 (5) implements 子句用于说明类中将实现哪些接口,接口是 Java 的一种引用类 型。 (6) 类体包含了变量和方法。在类体中定义的数据、变量和方法称为类的成员, 或称为实例变量和实例方法。 (7) 例如: 下例定义了一个 Point 类 ,并且声明了它的两个变量 x、y 坐标 ,同时实现 init()方法 对 x、y 赋初值 。 class Ponit { int x,y; void init(int ix, int iy){ x=ix; y=iy; } } 类中所定义的变量和方法都是类的成员。对类的成员可以设定访问权限 ,来限定 其它对象对它的访问,访问权限所以有以下几种:private, protected, public, friendly。 1.8.2 对象 把类实例化,我们可以生成多个对象,这些对象通过消息传递来进行交互(消息 传递即激活指定的某个对象的方法以改变其状态或让它产生一定的行为),最终完 成复杂的任务。一个对象的生命期包括三个阶段:创建对象、对象的引用和释放对 象 。 1.8.3 创建对象 创建对象包括声明、实例化和初始化三方面的内容。通常的格式为 : 1. 声明对象 对象声明实际上是给对象命名,也称定义一个实例变量。对象声明的一般格式为: type name 其中,type 是一个类的类名,用它声明的对象将属于改类;name 是对象名。 例如: Date today; Rectangle myRectangle; 第一条语句说明了对象 today 属于 Date 类,第二条语句说明了对象 myRectangle 属于 Rectangle 类。对象说明并没有体现一个具体的对象,只有通过实例化后的对 象才能被使用。 2. 实例化对象 实例化对象就是创建一个对象。实例化对象意味着给对象分配必要的存储空间,用 来保存对象的数据和代码。实例化后的每个对象均占有自己的一块内存区域,实例 化时,每个对象分配有一个"引用"(reference)保存到一个实例变量中。"引用" 实际上是一个指针,此指针指向对象所占有的内存区域。 因此,对象名(变量)实际上存放的是一个被实例化之后的对象所占有的内存区域 的指针。 例如: type objectName = new type ( [paramlist] ); 运算符 new 为对象分配内存空间 ,实例化一个对象 。new 调用对象的构造方法,返 回对该对象的一个引用(即该对象所在的内存地址)。用 new 可以为一个类实例化, 多个不同的对象。这些对象分别占用不同的内存空间,因此改变其中一个对象的状 态不会影响其它对象的状态 。 3.初始化对象 生成对象的最后一步是执行构造方法,进行初始化。由于对构造方法可以进行重写 ,所以通过给出不同个数或类型的参数会分别调用不同的构造方法。 例子:以类 Rectangle 为例,我们生成类 Rectangle 的对象: Rectangle p1=new Rectangle (); Rectangle p2=new Rectangle (30,40); 这里,我们为类 Rectangle 生成了两个对象 p1、p2,它们分别调用不同的构造方法, p1 调用缺省的构造方法(即没有参数),p2 则调用带参数的构造方法。p1、p2 分别对 应于不同的内存空间,它们的值是不同的,可以完全独立地分别对它们进行操作。虽 然 new 运算符返回对一个对象的引用,但与 C、C++中的指针不同,对象的引用是指 向一个中间的数据结构,它存储有关数据类型的信息以及当前对象所在的堆的地址, 而对于对象所在的实际的内存地址是不可操作的,这就保证了安全性。 1.8.4 对象的引用 对象的使用包括引用对象的成员变量和方法,通过运算符·可以实现对变量的访问和方法的调 用,变量和方法可以通过设定一定的访问权限(见下面的例子)来允许或禁止其它对象对它的 访问。 我们先定义一个类 Point。 例子: class Point{ int x,y; String name = "a point"; Point(){ x = 0; y = 0; } Point( int x, int y, String name ){ this.x = x; this.y = y; this.name = name; } int getX(){ return x; } int getY(){ return y; } void move( int newX, int newY ){ x = newX; y = newY; } Point newPoint( String name ){ Point newP = new Point( -x, -y, name ); return newP; } boolean equal( int x, int y ){ if( this.x==x && this.y==y ) return true; else return false; } void print(){ System.out.println(name+" : x = "+x+" y = "+y); } } public class UsingObject{ public static void main( String args[] ){ Point p = new Point(); p.print(); //call method of an object p.move( 50, 50 ); System.out.println("** after moving **"); System.out.println("Get x and y directly"); System.out.println("x = "+p.x+" y = "+p.y); //access variabl es of an object System.out.println("or Get x and y by calling method"); System.out.println("x = "+p.getY()+" y = "+p.getY()); if( p.equal(50,50) ) System.out.println("I like this point!!!! "); else System.out.println("I hate it!!!!! "); p.newPoint( "a new point" ).print(); new Point( 10, 15, "another new point" ).print(); } } 运行结果为: C:\java UsingObject a point : x = 0 y = 0 **** after moving ***** Get x and y directly x = 50 y = 50 or Get x and y by calling method x = 50 y = 50 I like this point!!!! a new point : x = -50 y = -50 another new point : x = 10 y = 15 1.引用对象的变量 要访问对象的某个变量,其格式为: objectReference.variable 其中 objectReference 是对象的一个引用,它可以是一个已生成的对象,也可以是能够生成对 象引用的表达式。 例如:我们用 Point p=newPoint();生成了类 Point 的对象 p 后,可以用 p.x,p.y 来访问该点的 x、y 坐标,如 p.x = 10; p.y = 20; 或者用 new 生成对象的引用,然后直接访问,如: tx=new point().x; 2.调用对象的方法 要调用对象的某个方法,其格式为: objectReference.methodName ( [paramlist] ); 例 如我们要移动类 Point 的对象 p,可以用 p.move(30,20); 虽然我们可以直接访问对象的变量 p.x、p.y 来改变点 p 的坐标,但是通过方法调用的方 式来实现能更好地体现面向对象的特点,建议在可能的情况下尽可能使用方法调用。 同样,也可以用 new 生成对象的引用,然后直接调用它的方法,如 new point(). move (30,20); 前面已经讲过,在对象的方法执行完后,通常会返回指定类型的值,我们可以合法地使 用这个值,如:例子中类 Point 的方法 equal 返回布尔值,我们可以用它来作为判断条件分别执 行不同的分支。如: if (p.equal (20,30)){ ...... //statements when equal }else { ...... //statements when unequal } 另外,类 Point 的方法 newPoint 返回该点关于原点的对称点,返回值也是一个 Point 类型,我们 可以访问它的变量或调用它的方法,如: px = p.newPoint().x 或 px = p.newPoint(). getX(); 1.8.5 成员变量 对象具有状态和行为,而对象的状态则是用变量或数据来描述的。在一个类中,对象的 状态是以变量或数据的形式定义的。 例如: "盒子"的体积的状态主要是宽度、高度、和深度。因此在类定义"盒子"对象时,只 将这三个属性作为其主要的状态,并用变量的形式来描述,这些变量称为成员变量。而在对 象实例化后,这些变量称为实例变量。 1.8.6 成员变量定义格式 成员变量定义的一般格式为: 【Modifer】type variablelist; 其中, type 指定变量的类型,它可以时 Java 的任意一种类型。 variablelist 是一组逗号隔开的变量名(变量列表),每个变量都可带有自己的初始化的表达 式。 例如: xint ,z; aint ,b=2,c=3; Modifer 是定义变量的修饰符,它说明了变量的访问权限和某些使用规则。变量修饰符可以 是关键字 public、protected、private、final、static、transient 和 volatile 的组合。 1.8.7 成员变量的初始化 当成员变量含有自己的初始化表达式时,可以创建实例的方式使成员变量实例化。 例如: class Box{ double width = 10; double height= 15; double depth= } 变量 width、height、depth 是成员变量。在执行 Box myBox1 = new Box()语句之后, new 运算符就创建了一个实例,并将变量分别赋初值为 10、15、20。在此时的变量 width、 height、depth 称为实例变量。 注意:在初始化表达式中,不能包含成员变量本身或同类的其他成员变量。例如,下面 的用法式错误的: class Test{ int int t =j; int } 错误有两个:一个式变量 k 的初始化涉及对 k 自身的访问;二式对 t 进行初始化时含有 对 j 的访问,而 j 的说明在其后。 1.8.8 成员变量的访问权限 成员变量或方法的访问权限是用访问权限修饰符来指定的。Java 的访问权限修饰符包括四种 显示方式修饰符和一种隐含方式修饰符,即: 1. 公用变量 用 public 说明的变量是公有变量。 访问权限:允许任何包中的任何类的变量访问。 例如:下面的代码中,在类 Alpha 中说明了一个公用变量 i_public,而在另一个类 Beta 中可以访问该变量。 class Alpha{ public int i_public ; } class Beta{ void accessmethod() { Alphaa= newAlpha(); a.i_public=10; } } 2. 私有变量 //说明公用变量 i_public //访问公用变量 i_public 用 private 说明的变量是私有变量。 访问权限:只能被定义它的类的变量访问。 例如:下面的代码中,在类 Alpha 中说明了一个私有变量 i_private,其他类不允 许访问。 正确的访问格式: class Alpha{ 3. 保护变量 } public int i_private ; void accessmethod() { Alphaa= newAlpha(); a.i_private=10; } //说明私有变量 i_private //访问私有变量 i_private 用 protected 说明的变量是保护变量。 访问权限:允许类自身、子类以及在同一个包中的所有类的变量访问。 例如:假定某个包 Geek 中含有两个成员类 Alpha 和 Beta,若在类 Alpha 中说明 了一个保护变量 i_protected,则在另外一个类 Beta 中可以访问该变量。 class Alpha{ public int i_protected; void accessmethod() } class Beta { void accessmethod() { Alpha a= new Alpha(); a.i_protected=10; } } 4. 私有保护变量 //说明保护变量 i_protected //访问保护变量 i_protected 用 private protected 说明的变量是私有保护变量。 访问权限:允许类自身以及它的子类变量访问。 例如:下面的两种访问方式是可行的。 (1) 在类中访问私有保护变量 例如: class Alpha{ private protected int i_pri_prot ; void accessmethod() { Alphaa= newAlpha(); } } a. i_pri_prot =10; //访问私有保护变量 i_pri_prot (2) 在子类中访问私有保护变量 例如: class Alpha{ private protected int i_pri_prot=10 ; } class Beta extends Alpha { void accessmethod() { Alphaa= newAlpha(); } } a. i_pri_prot =30; //访问私有保护变量 i_pri_prot 在程序执行时,变量 i_pri_prot 的值是 30,而不是 10; 5. 友好变量 如果一个变量没有显示地设置访问权限,则该变量为友好变量。 访问权限:允许类自身以及在同一个包中地所有类地变量访问。 例如:下面的类中定义了一个友好变量: class Alpha{ int i_friendly ; void accessmethod() { Alphaa= newAlpha(); } } a. i_friendly=10; //访问友好变量 i_friendly 在了解了成员变量的访问权限之后,那么在说明每一个成员变量时,都可以按访问权限给变 量提供适当的保护措施,这样就加强了变量的安全性。 名称 公用 私有 保护 私有保护 访问权限修饰 public private protected private protected 类 √ √ √ √ 子类 √ √ √ 包 √ * 所有类 √ √ 友好 friendly √ √ 注:表中√的为可选,打*的说明有特殊限制。*号是针对子类访问保护变量而言,即一个子类只有与超类 在同一个包中,才可以访问超类对象的保护变量。 1.8.9 静态变量 用 static 说明的变量是静态变量。静态变量与其他成员变量有区别:其他成员变量必须通过 类的对象来访问,每个对象都有这些变量的备份;而静态变量独立于改类中的任何对象,它 在类的实例中只有一个备份,可以直接使用,而不必通过类的对象去访问,它一直属于定义 它的类,因此也称为类变量。类的所有对象都共享 static 变量。static 变量通常也称为全局变 量。 例如: 静态变量的定义和引用。首先在类 MyDemo 中定义了 static 变量 x,y 然后在类 MyStaticDemo 中输入变量 x 和 y 的值。 import java.awt.Graphics; class MyDemo { static int x=80; static int y=120; } class MyStaticDemo extends java.applet.Applet { public void paint(Graphics g) { g.drawString("x="+MyDemo.x+"y="+MyDemo.y,25,50); } } 程序运行结果: x=80 y=120 在上面的程序中,在访问的静态变量 x 和 y 时,是通过类名 MyDemo 直接访问的。 static 也可以说明方法。用 static 说明的方法是静态方法或类方法,在实例中只有一 个备份。该方法具有以下约束: a) b) c) 它们仅可以调用其他 static 方法。 它们仅可以访问 static 变量。 它们不能参考 this 或 super。 如果类的成员被定义为 static,则可以通过下面形式引用: 类名,成员名 这里,类名是定义 static 成员所属的类。Java 通过这样的方式,实现了全局方法和变量。 1.8.10 final 变量 用 final 说明的变量可以当作一个常量使用,不得对其进行任何修改。若某此变量为了 防止被修改,则定义变量时必须初始化一个 final 变量。在这一点上,final 与 C\C++的 const 相似。比如: final int MONDAY=1; final int TUSDAY=2; final int WEDNESDAY=3; ...... 以后程序可以把上述变量当作常量来使用,而不用担心其被修改。 final 变量用大写字母来表示,这是一种习惯约定。final 变量不占内存空间,实际上也 就是一个常数。 1.9 方法 1.9.1 方法的定义 方法也是类的一个成员,定义方法时在定义类的同时进行的。其一般格式为: type name(parameter -list) { //方法体 } 格式说明: (1) type 指定方法的返回类型,简称方法的类型,它可以是任何有效的类型, 包括类类型。方法的返回或带值返回都由 return 语句实现,当一个方法没 有返回值时,其 type 必须为 void,且 return 语句可以省略。 (2) name 指定方法名,方法名可以是合适的 Java 标识符。 (3) parameter-list 指定方法的参数列表,参数包括参数的类型和参数名,每个 参数用逗号隔开。在定义方法时,其参数将作为形参;在调用方法时,其 参数被称为实参。调用时是把实参的值传递给形参。入过方法没有参数, 参数列表为空,但括号"()"不能省略。 (4) 方法体包含了一组代码,它用于对数据处理。方法体用以对大括号"{}"括 起来。 例如:Box 类封装"盒子"的状态和行为,即数据变量和方法,用方法 volume 计 算 Box 对象的体积。 import java.awt.Graphics; class Box { double width; double height; double depth; void setDemo(double w,double h,double d) { width=w; height=h; depth=d; } } double volume() { return width*height*depth; } class BoxDemo extends java.applet.Applet { public void paint(Graphics g) { double d_volume; Box myBox = new Box(); myBox.setDemo(10,20,30); //调用方法 setDemo 给变量赋值 d_volumn = myBox.volume(); //计算体积 g.drawString("myBox 的体积是:"+ d_volumn,25,50); } } 程序运行的结果如下: myBox 的体积是:6000 1.9.2 方法的访问权限 方法同成员变量一样,可以在定义时说明方法的访问权限,其说明格式和访问机制与成 员变量完全一样。 例如:私有方法、私有保护方法只能被同一个类中的方法调用,公用方法可以被其他类 的方法调用。 import java.awt.Graphics; class Alpah1 { pivateint i_private() { int x=10; int y=20; return x+y; } public int i_public1() { return i_private(); } } class Alpah2 { public public int x,y; private protected int i_protected(int a,int h) { x=a; y=b; return x+y; } public void i_public2(int i,int j) { k=i_protected(i,j); } } class Test extends java.applet.Applet { public void paint(Graphics g) { int p1; Alpah1 ap1= newAlpah1(); Alpah2 ap2= newAlpah2(); p1=ap1.i_public1(); ap2. i_public2(50,50); g.drawString("i_public1()的返回值是:"+p1,25,50); g.drawString("i_public2()的返回值是:"+ap2.k,25,50); } } 程序运行的结果如下: 方法 i_public1()的返回值是:30 方法 i_public2()的返回值是:100 程序说明: (1)在类 Alpah1 中,方法 i_private()是私有的,它只能被同类的方法 i_public1()调用。 而方法 i_public1()是公有的,它可以被另一类 Demo 中的方法 paint()调用。 (2)在类 Alpah2 中,方法 i_protected()是私有保护性的,它不能被其他类的方法调用, 而只能被同类(或子类)的方法 i_public2()调用。同样,方法 i_public2()也是公有的,它可 以被另一类 Test 中的方法 paint()调用。 (3)在方法 i_public1()中,语句 return i_private()执行的顺序为:先调用,后返回。其 返回值是 x+y 的和。 (4)在方法 i_public2(int i,int j)中,将形参 i 和 j 作为调用方法中的实参。 如:k=i_protected(i,j); (5) 在类 Alpha2 中,定义了成员变量 k、x 和 y。其中 k 是公有的,它可被类 Test 中 的方法引用,其格式为:ap2.k;而变量 x 和 y 是私有的。它只能被同一类的方法引用。 (6)在类 Alpah1 方法 i_private()中,定义的变量 x 和 y 是局部变量。 局部变量作用域是:只能在定义它的方法中有效,即使同一类中的方法也不能引用。 例如:方法 i_public()是不能访问局部变量 x 和 y 的。 1.9.3 对象作为参数 例:给定两个数,按大小顺序输出。 import java.awt.Graphics; class Test1 { public int a,b; void mov(int i,int j) { a=i; b=j; } } class Test2 { void max(Test1 test1) { int c; if(test1.a<test1.b) { c=test1.a; 引用 test1 对象的成员变量 a。 test1.a = test.b; test1.b=c; } } } class MaxTest extends java.awt.Applet { public void paint(Graphics g) { Test1myTest1=new Test1(); Test2 myTest2 = new Test2(); myTest1.mov(45,55); //调用 Test2 类的方法 max,并将对象 myTest1 作为实参。 myTest2.max(myTest1); g.drawString("大小顺序为:"+ myTest1.a+","+myTest1.b,25,50); } } 1.9.4 对象作为返回值 下面的例子是把对象作为返回值的编程方法。 例如:利用方法返回对象的特性,实现对实例变量的值的递增。 import java.awt.Graphics; class Test { public int a,b; void mov( int i,int j) { a=i; b=j; } Test max() //方法 max()的返回值类型是 Test 类型 { Test myTest = new Test(); myTest.mov(a+10,b+10);使实例变量的值增 10。 return myTest; } } class OutMyDemo extends java.applet.Applet; { public void paint(Graphics g) { Test p1 = new Test(); Test p2; p1.mov(15,55); g.drawString("p1 的实例变量值:a="+pa1.a+",b="+pa1.b,25,75); p2=p2.amx(); g.drawString("p2(p2 加 10)的值:a="+p2.a+",b="+p2.b,25,100); } } 程序运行的结果如下: p1 的实例变量值:a=15,b=55; p2(p1 加 10)的值:a=15,b=65; p2(p2 加 10)的值:a=35,b=75; 1.10 构造方法 1.10.1构造方法概述 构造方法是一个在创建对象初始化的方法,它具有与类相同的名字。事实上,除了构造 方法,在类中不能再有别的方法与类同名。一旦定义了构造方法,在执行 new 操作期间, 首先创建对象,然后自动调用构造方法将对象初始化。 与其他方法不同,构造方法必须在 new 运算符中引用,而不能按引用一般方法的格式 去引用构造方法。 在同一个类中,允许定义多个构造方法。这些构造方法是以参数的个数来区分的。在创 建对象时,程序员应当根据参数的个数和类型来选择合适的构造方法。 如果一个类中没有包含构造的说明,将提供隐含的构造方法,隐含的构造方法没有参数, 它将调用超类中不带参数的构造方法,如果超类中没有不带参数的构造方法,将产生编译错 误。 构造方法有些特殊,它没有返回类型甚至 void。因为构造方法的缺省返回类型是类类型 本身。构造方法的另一个特殊性是它不能继承超类。 例子: import java.awt.Graphics; class Test { double width; double height; double depth; Test(double w,double h,double d) //定义构造方法 Box() { width = w; height = h; depth=d; } double volume() { return width*height*depth; } } class Testing extends java.applet.applet { public void paint(Graphics g) { double d_volume; Test test = new Test()//new 运算符创建对象 test 后,随即对 test 初始化。 } } d_volume = test.volume();//计算体积 g.drawString("test 的体积是:"+d_volume,25,50); 程序运行的结果如下: test 的体积是:6000 1.10.2构造方法的访问权限 在定义构造方法时可以对他们附加访问修饰符,它们时: pulic(公有型的构造方法) private (私有型的构造访问) proected (保护型的构造方法) private protected (私有保护型的构造方法) 这四种方法访问修饰符的权限范围和方法的访问权限的范围一样。构咱方法的访问修饰符不 能是 abstract、static、final、native 或 synchronized; 1.11 方法重载 在 java 中,可以在同一个类中定义多个同名的方法,只要它们的参数列表不同,这叫做方 法的重载(Overload)。方法重载是 Java 最具有吸引力的有利特征。 当一个重载方法被激起时,Java 便根据参数的类型和数目确定被调用的方法。这样,重载方 法之间一定具有不同的参数列表,包括参数的类型和数目。 例:给定两个或三个数,将它们由大到小按顺序输出。 import java.awt.Graphics; class Test { double max1,max2,nax3; Test() { max1=-1; maxe2=-1; max3=-1; } void sort(double i,double j) { double s; max1=i; max2=j; if( max1<max2) { s=max1; max1=max2; } } max2=s; } void sort(double I,double j,double k) { double s; max1=i; max2=j; max3=k; if(max1<max2) { s=max1; max1=max2; max2=s; } if(max1<max3) { s=max1; max1=max3; max3=s; } if(max2<max3) { s=max2; max2=max3; max3=s; } } class outMaxTest extends java.awt.Applet { public void paint(Graphics g) { Testt1=new Testt(); t1.sort(200,300); g.drawString("两个数的大小顺序为:"+ t1.max1+","+t1.max2,25,10); t1.sort(100.9f,200.9f,300.9f); g.drawString("三个数的大小顺序为:"+ t1.max1+","+t1.max2+","+t1.max3,25,30); } } 程序运行的结果如下: 两个数的大小顺序为:300,200 三个数的大小顺序为:300.9,200.9,100.9 在上面的代码中,类 Test 中定义了三个方法: Test()是一个无参的构造方法,它在创建对象之后紧接着对变量进行初始化。如果没有该 方法,在创建对象时将产生编译错误。因为类 Test 是直接超类。 两个 sort()是排序方法,它们是用参数的数目来区分的,这两个 sort()方法能对任 何数字类型的数据进行排序。当然,对多个数据进行排序最好用数组来实现。 1.12 this 1.12.1用 this 引用成员变量 例子:在构造方法中使用 this,this 代表当前对象的引用参考,并将参数值赋值到成员 变量 max1、max2 和 max3 中。 import java.awt.Graphics; class Test { double max1; double max2; double max3; Test(double i,double j) { this.max1=i; this.max2=j; this.max3=k; } } class Test1 extends java.awt.Applet { public void paint(Graphics g) { Test t = new Test(10,20,30); g.drawString(t.max1+","+t.max2+","+t.max3,25,30); } } 程序运行的结果如下: 10,20,30 1.12.2在构造方法中用 this 调用一般方法 例子:在构造方法中使用 this 调用 sort()方法。 import java.awt.Graphics; class Test { double max1,max2,max3; Test(double i,double j) { max1=i; max2=j; this.sort(i,j); //调用 sort 方法,将两个数排大小顺序。 } Test(double i,double j,double k) { max1=i; max2=j; max3=k; this.sort(i,j,k) //调用 sort 方法,将三个数排大小顺序。 } void sort(int i,double j) { double s; if(max1<max2) { s=max1; max1=max2; max2=s; } } void sort(double i,double j,double k) { double s; if(max1<max2) { s=max1; max1=max3; max2=s; } if(max1<max3) { s=max1; max1=max3; } max3=s; } } if(max2<max3) { s=max2; max2=max3; max3=s; } class ThisTest extends java.applet.Applet { public void paint(Graphics g) { Test t1 = newTest(10,100); g.drawString("两个数的大小顺序为:"+t1.max1+","t1.max2,25,10); Test t2 = new Test(100,10,1000); g.drawString("三个数的大小顺序为:"+t2.max1+","t2.max2+","+t2.max3,25,30); } } 程序运行的结果如下: 两个数的大小顺序为:100,10 三个数的大小顺序为:1000,100,10 1.12.3在方法中用 this 调用另外一个方法 例子:在上面的例子上加一个方法 mov(),在 mov()中引用 this 再调用 sort()方法。 import java.awt.Graphics; class Test { double max1,max2,max3; Test(double i,double j) { max1=i; max2=j; this.sort(i,j); //调用 sort 方法,将两个数排大小顺序。 } void sort(int i,double j) { double s; if(max1<max2) } { } s=max1; max1=max2; max2=s; } void mov(double i,double j) { max1=i; max2=j; this.sort(i,j); } class ThisTest extends java.applet.Applet { public void paint(Graphics g) { Test t1 = newTest(10,100); t1.mov(20,200); g.drawString("两个数的大小顺序为:"+t1.max1+","t1.max2,25,10); } } 程序运行的结果如下: 两个数的大小顺序为:200,20 注意:再初始化之后,变量 max1 和 max2 的值分别为 10 和 100,当调用 mov()之后, 其值为 20 和 200。 1.13 类的继承 继承是面向对象程序设计的重要概念之一。在 java 中,被继承类称为超类,继承称为 子类。通过继承可使子类继承超类的特征和功能。其基本规则如下: (1) 子类可继承其超类的代码和数据,即在子类中可以直接执行超类的方法和访问超类 的数据。 (2) 在子类中可以增加超类中没有的变量和方法。 (3) 在子类中可以重新定义超类中已有的变量(包括实例变量和类变量)。变量的重新 定义被称为变量的隐藏,也就是说,在子类中允许定义与超类同名的变量。 (4) 在子类中可以重载超类中已有的方法(包括构造方法、实例方法和类方法)。 (5) 在子类的构造方法中,可以通过 super()方法将超类的变量初始化。 (6) 当超类为抽象类时,子类可继承超类中的抽象方法,并在子类中去实现该方法的细 节。 1.13.1 创建子类 实现继承要用 extends 关键词,其格式如下: 子类名 extends 超类名 (1) 继承超类的方法和变量 例子:给定三个数,将它们按大到小的顺序输出。在下面的程序中,子类 Test1 继承超类 Test 的全部代码和变量。在子类的方法中,调用超类的方法 sort()和更 新数据。 import java.awt.Graphics; class Test { double max1,max2,max3; Test() { max1=-1 max2=-1; max3=-1; } void sort() { double s; if(max1<max2) { s=max1; max1=max2; max2=s; } if(max1<max3) { s=max1; max1=max3; max3=s; } if(max2<max3) { s=max2; max2=max3; max3=s; } } } class Test1 extends Test { void subsort(double i,doublej,double k) { max=i; max2=j; max3=k; sort(); //调用超类 Test 中的方法 sort() } } class SortTest extends java.applet.Applet { public void paint(Graphics g) { Test1t1 =new Test1(); t1.subsort(100,.300,200); g.drawString("三个数的大小顺序为:"+t1.max1+","t1.max2+","+t1.max3,25,30); } } 程序运行的结果如下: 三个数的大小顺序为:300,200,100 (2) 隐藏实例变量和类变量 在子类中,若定义了与超类同名的变量,则只有子类中的变量有效,而超类中 的变量无效。 例:数据求和。 import java.awt.Graphics; class Test { double sum,num1,num2; static int num3; Test() { num1=0; num2=0; num3=0; sum=0; } } class Test1 extendsTest { int sum,num1,num2; //隐藏超类 Test 中的实例变量 static int num3; //隐藏超类 Test 中的类变量 } void sum(int i,int j,int k) { num1=i; num2=j; num3=k; sum=num1+num2+num3; } class SumTest extends java.awt.Applet { public void paint(Graphics g) { Test1t1 =new Test1(); t1.sum(100,200,300); g.drawString("sum="+ t1.num1+"+"+t1.num2+"+"+t1.num+"="+t1.sum,25,30); } } 程序运行的结果如下: sum=100+200+300+=600 (3)访问权限 尽管子类可以继承超类的所有成员,但子类不能继承超类中的私有变量和方法,而只能 继承如下变量和方法。 .超类中定义为公有的、私有保护的或保护的成员变量和方法可被子类访问。 .同一个包中的超类的友好变量和方法可被子类访问。 (4)用继承的方法来扩充超类的功能 如果子类只继承超类的代码和数据是没有多大意义的,对继承来说,其真正的目的是想 通过子类来扩充超来的功能,只有这样,才能有效发挥继承的作用。 例:从超类 Box 中只计算"盒子"的体积,但在子类 SubBox 中不仅只计算"盒子"的 体积,而且还能求得它重量。 import java.awt.Graphics; class Box { double width; double height; double depth; Box(double w,double h,double d) { width=w; height=h; } Box() { depth=d; } width=-1; height=-1; depth=-1; } double volume() { return width*height*depth; } class SubBox extends Box { double weight; SubBox(double w,double h,double d,double m) { width=w; height=h; depth=d; weight=m; } } class Test extends java.awt.Applet { public void paint(Graphics g) { double d_volume; Box box1=new Box(10,20,30); d_volume=box1.volume(); //计算 box1 的体积 } } g.drawString("box1 的体积是:"+d_volume,25,50); SubBox subBox = new SubBox(15,15,20,40); d_volume= subBox.volume(); g.drawString("subBox 的体积是:"+d_volume,25,75); g.drawString("subBox 的体积是:"+subBox.weight,25,90); 程序运行的结果如下: box1 的体积是:6000; subBox 的体积是:4500 subBox 的重量是:40 1.13.2 重载超类的方法 要使多态性在程序中设计运用成功,不仅要求超类给子类提供可直接使用的元素,更重要的 是在类层次结构中具有一致的接口,使子类在超类的基础上扩充超类的功能。 例:超类 Test 中方法 sort()实现对 n 个整个升序排列,子类 Test1 中的 sort()实现对 n 个整数 按降序排列。 import java.awt.Graphics; class Test { int Test() { i=j=k=swap=0; } void sort(int t1,int t2[ ]) //用选择法按升序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;i<t1-1;j++) { if(t2[j]<t2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } } } } class Test1 extends Test { void sort(i=0;i<t1-1;i++)//重载超类中的方法 sort(),用选择法按降序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;it2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i] =t2[k] t2[k]=swap; } } } } } class SortTest extends java.awt.Applet { public void paint(Graphics g) { int a[]={34,12,8,67,88,23,98,101,119,56}; g.drawString("排序前的数据为:",20,10); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,30); } Test t1=new Test(); t1.sort(a.lenght,a); //调用 Test 类的方法 g.drawString("按升序排列的数据为:",20,50); for(int i=0;i<10;i++) { } g.drawString(""+a[i],20+i*30,70); } } Test1 t2=new Test2(); t2.sort(a.lenght,a); g.drawString("按降序排列的数据为:",20,90); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,110); } 程序运行的结果如下: 排序前的数据为: 34 12 8 67 88 23 98 101 119 56 按升序排列的数据为: 8 12 23 34 56 67 88 98 101 119 按降序排列的数据为: 119 101 98 67 56 34 23 12 8 1.13.3 super super 是一个方法,其格式为: super(parameter-list) 其中,parameter-list 是参数列表。super()的作用是调用超类的构造方法。降超类中的变量初 始化。super()总是用于子类的构造方法中,而且在子类的构造方法中最先执行 super().因此, 只有 parameter-list 与超类的构造方法中的参数相匹配,才能有效调用超类的构造方法去实现 对超类的变量初始化。同时,在子类中也减少了初始化编码的重复工作。 super()的用法请见下面的例子: 例:在下面的例子里,将子类的构造方法中的赋初值改用 super()方法来完成 import java.awt.Graphics; class Box { double width; double height; double depth; Box(double w,double h,double d) { width=w; height=h; depth=d; } Box() { } width=-1; height=-1; depth=-1; } double volume() { return width* height* depth; } class SubBox extends Box { double weight; SubBox(double w,double h,double d,double m) { super(w,h,d); weight=m; } } class BoxTest extends java.awt.Applet { public void paint(Graphics g) { double d_volume; Box box1=new Box(10,20,30); d_volume=box1.volume(); //计算 box1 的体积 } } g.drawString("box1 的体积是:"+d_volume,25,50); SubBox subBox = new SubBox(15,15,20,40); d_volume= subBox.volume(); //计算 subBox 的体积 g.drawString("subBox 的体积是:"+d_volume,25,75); g.drawString("subBox 的体积是:"+subBox.weight,25,90); 程序运行的结果如下: box1 的体积是:6000; subBox 的体积是:4500 subBox 的重量是:40 但要注意的是: (1) super(w,h,d)用于子类的构造方法 SubBox()中。 (2) super(w,h,d)中的参数应与超类的构造方法参数相匹配,即参数个数及类型 一样。 1.13.4 abstract 当要求将一个超类定义为抽象类时,前面加关键字 abstact。其格式如下: abstract 类型 类名{} abstract 的作用是说明该类是一种抽象结构。抽象结构的类包含了一些抽象的方法,而这些 抽象方法只有方法的形式,即方法体是空的,方法体的细节由子类去实现。抽象方法的定义 也由关键字 abstract 来说明,其格式为: abstract 类型 方法名{parameter-list}; { 其中,parameter-list 是参数列表。因此,整个抽象类的结构如下形式: 成员变量 1; 。。。。。 构造方法 。。。。。。 abstract 类型 方法名(parameter-list); } 抽象类的定义也是多态的一种体现。因为多态性具有子类重载超类中的方法的特性,而在超 类中只限定子类重载规定的方法,但这些方法的细节必须由子类来完成。所有,常把这样的 类作为抽象类。 抽象类不能直接用 new 运算符实例化一个对象。抽象方法只能是实例化方法,它不包括子 类对象。 例:在抽象类 Test 中,定义一个抽象方法 sort(),并在子类 Test1,Test2 中,分别去实现超类中 的抽象方法 sort()的细节,从而分别完成对 n 个整数的降序、升序的排列。 import java.awt.Graphics; abstract class Test { int i,j,k,swap; Test() { i=j=k=swap=0; } abstract void sort(int t1,int[] t2); //定义一个抽象的方法。 } class Test1 extends Test { void sort(int t1,int t2[ ]) //重载超类的方法 sort(),用选择法按降序排列 { for(int i=0;i<t1-1;i++) { k=i; } } for(i=0;it2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } class Test2 extends Test { void sort(int t1,int t2[ ]) //重载超类的方法 sort(),用选择法按升序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;i<t1-1;j++) { if(t2[j]<t2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } } } class SortTest extends java.awt.Applet } { public void paint(Graphics g) { int a[]={34,12,8,67,88,23,98,101,119,56}; //Test k=new Test(); 此句是非法的,不能创建实例对象。 Test1 k1=new Test1(); k1.sort(a.length,a); g.drawString("按降序排列的数据为",20,10); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,30); } Test2 t2=new Test2(); t2.sort(a.lenght,a); g.drawString("按升序排列的数据为:",20,50); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,70); } 程序运行的结果如下: 按降序排列的数据为: 119 101 98 67 56 34 23 12 8 按升序排列的数据为: 8 12 23 34 56 67 88 98 101 119 通过本例可以发现抽象类的好处:从一个抽象类可以派生出多个子类,而且在各个子类中允 许对同一个抽象方法产生不同的方法体。 1.13.5 final final 有三个用途:其一,可以用于创建与常量一样的变量,其二,另外 2 个用途就是防止 类被继承或方法被重载。 1. 最终类 Java 引入了最终类的概念,所谓最终类既是那些不能再有子类的类。说明最终类时可以 在最前面加上修饰符 final。 例:final class A { //.... } class B extends A //错误!不能从 A 类派生 { //....... } 注意:不能将一个抽象类说明为 final 类,因为抽象类必须要被派生类来实现它的抽象 方法。当一个类被说明为 final 类后,也相当于隐式的说明了它的所有方法为 final。 1.14 java 包,接口和异常 包是类的容器,用于保证类名空间的一致性。包以层次结构组织并可被明确地引入到一 个新类定义。 接口是方法的显示说明,利用接口可以完成没有具体实现的类。接口虽然与抽象类相似, 但它具有多继承能力。一个类可以有无数个接口,但是只能从一个父类派生。 异常是代码运行时出现地非正常状态。Java 的异常是一个出现在代码中描述异常状态的 对象。每当一个异常情况出现,系统就创建一个异常对象,并转入到引进异常的方法中,方 法就根据不同的类型捕捉异常。为防止由于异常而引起的退出,在方法退出前应执行特定的 代码段。 1.14.1 包 1.14.1.1 package 语句 包是一种命名和可视控制的机制,用户可以把某些类定义在一个包 中,也可以对定义在这个包中的类施加访问权限,以限定包外或包 内的程序对其中的某些类进行访问。 定义包的格式: package pkg; Java 的文件系统将存储和管理这个包。例如:属于 pkg 包中的.class 文件将存储到目录 pkg。注意:目录与包的名字完全一样。 package 语句可以创建包的层次结构,通过使用逗号,把每个包分开。 多级包层次结构的一般格式为: package pkg1[.pkg2[.pkg3]] 包层次结构必须反映 Java 开发系统的文件系统。比如:pacakge java.awt.Image; 1.14.1.2 import 语句 import 语句的功能是引入包或包中的类。它们必须位于 package 语 句与这个文件的类或接口之间。 格式:import pkg1[.pkg2.(classname|*)] 这里,pkg1 是顶层包名,pkg2 是下一层包名,其间用点隔开。除了 对文件系统的限制外,对包的层次深度没有限制。最后以一个显示 方式指定一个类名 classname 或*号,星号*指示 Java 编译器应该引入 整个包。 例子: import java.awt.Image; import java.lang.*; 1.14.2 接口 1.14.2.1 接口的概念 接口与类存在着本质的差别,类有它的成员变量和方法,而接口只有 常量和方法协议,从概念来讲,接口是一组方法协议和常量的集合。 接口在方法协议与方法体实体之间只起到一种称之为界面的作用,这 种界面限定了方法实体中的参数类型一定要与方法协议中所规定的 参数类型保持一致,除此以外,这种界面还限定了方法名、参数个数 及方法返回类型的一致性。因此,在使用接口时,类与接口之间并不 存在子类与父类的那种继承关系,在实现接口所规定的某些操作时只 存在类中的方法与接口之间保持一致的关系,而且一个类可以和多个 接口之间保持这种关系,即一个类可以实现多个接口。 1.14.2.2 接口的定义 格式: access interface name { return method-name(parameter-list); type final-varname=value; } 其中,access 是访问修饰符。它只有 public 和未指定访问修饰符 两种情况。当未指定访问修饰符时,该接口只能为同一个包中的 其他成员所用;当 public 修饰符说明时,该接口可以被其他任何 代码使用。name 是接口的名字,可以是任何有效的标识符。接 口体包括方法协议和常量,它们都用分号结束。在接口中定义的 常量必须用变量名标识。他们隐式为 final 和 static,不能被实现 类所改变。 例:interface Back { void c_back(int param); int SOON=4; } 该接口定义了一个方法协议,其参数为整数类型;还定义了一整 数常量,其变量名为 SOON。该接口只能为同一个包中其他成员 所用。 1.14.2.3 接口的实现 一旦接口被定义,类就可以实现它。在类的定义中可以使用关键 字 implements 实现接口,然后在类中创建接口中所定义的方法, implements 关键字的类的格式: access class classname[extends superclass] [implements interfacename[,interface...]] { } ..... 例子:定义两个接口,其方法协议分别完成两个数的加法和减法 操作,然后分别实现这两个接口的方法。 import java.awt.Graphics; interface Demo_Add { public int add(int x,int y); } interface Demo_Sub { public int sub(int x,int y); } class Demo_Add_Sub implements Demo_Add, Demo_Sub { public int add(int x,int y) { return i+y; } public int sub(int x,int y) { return x-y; } } public class Add_Sub extends java.awt.Applet { public void paint(Graphics g) { Demo_Add_Sub k=new Demo_Add_Sub(); g.drawString("x+y="+k.add(30,10),30,30); g.drawString("x-y=" + k.sub(30,10),30,50); } } 程序运行结果如下: x+y=40; x-y=20; 1.14.2.4 接口的继承 一个接口可以继承其他接口,这可通过关键字 extends 来实现,其语 法与类的继承相同。当一个类实现一个派生接口时,必须实现所有 接口及其派生接口中所定义的全部方法协议。 例:定义 5 个接口,其中两个超接口。 import java.awt.Graphics; //定义接口 Test_C interface Test_C { public int add(int x,int y); } interface Test_B extends Test_C { public int sub(int x,int y); } interface Test_A extends Test_B { public int mul(int x,int y); } //定义接口 Test_Y interface Test_Y { public int div (int x,int y); } interface Test_X extends Test_Y { public int mod (int x,int y); } //定义类 Test class Test implements Test_A ,Test_X { public int add(int x,int y) { return x+y; } public int sub(int x,int y) { } return x-y; } public int mul(int x,int y) { return x*y; } public int div (int x,int y) { return x/y; } public int mod (int x,int y) { return x%y; } public class Add_Mod extends java.awt.Applet { public void paint(Graphics g) { Test k =new Test(); g.drawString("x+y="+k.add(66,10),30,10); g.drawString("x-y="+k.sub(66,10),30,10); g.drawString("x*y="+k.mul(66,10),30,10); g.drawString("x/y="+k.div(66,10),30,10); g.drawString("x%y="+k.mod(66,10),30,10); } } 程序运行结果如下; x+y=76 x-y=56 x*y=660 x/y=6 x%y=6 注意:在类中实现一个接口时,任何类都必须实现该接口或接口树的所有方法。 1.14.3 异常处理 所谓异常就是代码在运行时发生的非正常状态。Java 的异常是一个出现在代码中描 述异常状态的对象。每当出现一个异常情况,就创建一个异常对象,并向导致错误 的方法中抛出该对象。该方法捕捉到异常对象之后,可以选择用来处理该异常或不 管它。异常通常由 Java 运行系统产生,或者由用户的程序代码产生。Java 抛出的异 常大多是用户违背了 Java 语言的基本规则,或者超出了 Java 执行环境的约束。 1.14.4 异常处理机制 Java 通过 5 个关键字 try、catch、throw、throws 和 finally 管理异常处理。 try 用来监视它所在的那个程序块是否发生异常,如果发生异常就抛出它。对于系统 产生的异常或程序块中未用 try 监视所产生的异常,将一律被 Java 运行系统自动抛 出。 catch 用来捕捉 try 程序所抛出的异常,将一律被 Java 运行系统自动抛出。 throw 可以用以人工地抛出一个异常 throws 用于从一个方法中抛出一个异常。 finally 用于调用缺省异常处理。 下面是异常处理地一般形式: try { //有可能会出错地代码块,被 try 监视。 } catch(ExceptionType1 ex) { //关于 ExceptionType1 的异常处理 } catch(ExceptionType2 ex) { //关于 ExceptionType2 的异常处理 } //...... finally { //在 try 块结束前被执行的代码块。 } 1.2 常用类 System 类 全称:java.lang.System 扩展:Object 描述:公有最终类。此类与 Runtime 一起可以访问许多有用的系统功能。有一些方法在 两个类中都出现。exit()、gc()、load()和 loadLibrary()可以通过调用 Runtime 中的同名方 法来响应。特别有用的是类变量 err、in 和 out,它们可以访问基本控制台 I/O。System 类完全由类域组成,这些类域可以通过"System.变量名"和"System.方法()"的方法 进行访问。此类不能被实例化。 实例变量: public static PrintStream err; public static InputStream in; public static PrintStream out; 每个变量对整个程序而言都是唯一的对象变量。这些对象可以访问系统的输入、输出和 错误输出。 常用类方法: void exit(int status) 导致 Java 程序退出,向系统传递指定的状态代码。 void gc() 请求立即激活垃圾收集器开始清除不再使用的对象。 String getProperty(String key) String getProperty(String key,String def) 在系统属性表中查找的一个属性。如果未发现属性,而且在 getProperty()方法中指定了 参数 def,那么返回 def。 SwingUtil.ities 类 全称:javax.swing.SwingUtilities 扩展:Object 描述:公用类。此类中包含了一组在 Swing 工具包中使用的帮助器方法 常用类方法: void paintComponent(Graphics g,Component c,Container p,int x,int y,int w,int h); void paintComponent(Graphics g,Component c,Container p,Rectangle r); void invokeLate(Runnable doRun); boolean isEventDispatchThread(); Component getRoot(Component c); JRootPane getRootPane(Component c);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值