软件构造学习笔记——ADT+OOP 第4-8讲,习题课2

本部分重点考察大题

有以下考点

目录

第四讲

 基本数据类型、对象数据类型。

 静态/动态类型检查

 Mutable/Immutable

 值的改变、引用的改变、final

 防御式拷贝

 Snapshot diagram

 第五讲

 Specification、前置/后置条件

 行为等价性

 规约的强度

P规约设计

第六讲

 ADT操作的四种类型

 表示独立性、表示泄露

 不变量、表示不变量RI

 表示空间、抽象空间、AF

 以注释的形式撰写AF、RI

第七讲

 接口、抽象类、具体类

 继承、override

 多态、overload

 泛型

 Some important Object methods in Java

 等价性equals()和==

 equals()的自反、传递、对称


第四讲

 基本数据类型、对象数据类型。

 静态/动态类型检查

java是静态类型语言

静态 类型语言:在编译阶段进行类型检查,所有变量的类型在编译期就已经确定
动态类型语言:在运行阶段进行类型检查,变量的类型在运行期才能确定

静态类型检查:可发现语法错误、类名 / 函数名错误、参数数目错误、参数类型错误、返回值类型错误
静态类型检查可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性
/ 健壮性
动态 类型检查:可发现非法的参数值、非法的返回值、越界、空指针

静态类型检查是关于“类型”的检查,不考虑值;动态检查是关于“值”的检查。
Java 是一种静态类型语言,它同时具有静态类型检查和动态类型检查。

静态检查 >> 动态动态 >> 无检查

 Mutable/Immutable

不变数据类型(immutable type):一旦被创建,其值不能改变
引用不变:一旦确定其指向的对象,不能再被改变(但其值是可能变化的)

对于不可变类型,频繁对其运算会产生大量的临时拷贝,可变类型能最少化拷贝以提高效率。因此,使用可变数据类型,可获得更好的性能,也适合于在多个模块之间共享数据。

而不可变类型更“安全”, 在其他质量指标上表现更好。例如,向任何方法传入不可变类型的值,不用担心其值被意外修改;多线程可以安全地持有同一个不可变类型的引用,而不用担心竞争。

 值的改变、引用的改变、final

改变一个变量:将该变量指向另一个值的存储空间
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值

Java 中的 final 关键字

final 类无法派生子类
final 方法无法被子类重写

       •final 变量无法改变其引用(而非值)

 防御式拷贝

通过防御式拷贝,给客户端返回一个全新的Date对象

大部分时候该拷贝不会被客户端修改, 可能造成大量的内存浪费

如果使用不可变类型, 则节省了频繁复制的代价

不可变类型 不需要防御式拷贝

//保护可变类型的另一种方法

单引用局部变量:把对 mutable 对象的引用限制在类 / 方法内,不对外暴露
如果存在多个引用,使用可变类型就非常不安全

 Snapshot diagram

 不可变对象:用双线 椭圆

//

迭代器是一个可变数据类型,它拥有两个方法:mutator 方法 next() 返回容器的下一个数据;observer 方法 hasNext() 返回容器是否还有下一个数据。

 

a code-level, run-time, and moment view

//

 第五讲

 Specification、前置/后置条件

图表规约

静态类型声明是一种规约,可据此进行 静态类型检查static checking。

方法前的注释也是一种规约,但需人工判定其是否满足

 除 非在后置条件里声明过,否则方法内部不应该改变输入参数

前置条件:对客户端的约束,在使用方法时必须满足的条件

后置条件:对开发者的约束,方法结束时必须满足的条件

如果前置条件满足了,后置条件必须满足

前置条件不满足,则方法可做任何事情

 行为等价性

站在客户端视角看行为等价性

根据规约 判断是否行为等价

 规约的强度

前置条件更弱或相等(不强于)

后置条件更强或相等(不弱于)

就可以用S2替代S1

P规约设计

coherent (内聚的)  Spec描述的功能应单一、简单、易理解

informative信息丰富的 不能让客户端产生理解的歧义

太弱的spec,client不放心、不敢用 (因为没有给出足够的承诺)。 开发者应尽可能考虑各种特殊情况,在post-condition给出处理措施。

太强的spec,在很多特殊情况下难以达到,给开发者增加了实现的难 度(client当然非常高兴)

在规约里使用抽象类型,可 以给方法的实现体与客户端更大的自由度

是否使用前置条件取决于(1) check的代价;(2) 方法的使用范围 – 如果只在类的内部使用该方法(private),那么可以使用前置条件(方法内部 不需要判断输入是否满足,认为client会保证前置条件),在使用该方法的各 个位置进行check——责任交给内部client; – 如果在其他地方使用该方法(public),那么可以不使用/放松前置条件(在方 法内部检查输入是否满足),若client端不满足则方法抛出异常。

第六讲

 ADT操作的四种类型

Creators 构造器(从无到有)

构造器:可能实现为构造函数或静态 函数

实现为静态方法的构造器通常称为工厂方法

Producers 生产器(从 有到新)

Observers 观察器

Mutators 变值器,改变对象属性的方法

变值器通常返回 void

如果返回值为void,则必然意 味着它改变了对象的某些内部状态

 表示独立性、表示泄露

表示独立性:client使用ADT时无需考虑其内部如何实 现,ADT内部表示的变化不应影响外部spec和客户端。

 不变量、表示不变量RI

由ADT 来负责其不变量,与client端的任何行为无关

▪ 表示不变性RI:某个具体的“表示”是否是“合法的” ▪ 也可将RI看作:所有表示值的一个子集,包含了所有合法的表示值 ▪ 也可将RI看作:一个条件,描述了什么是“合法”的表示值

在所有可能改变rep的方法内都要检查

Observer方法可以不用, 但建议也要检查,以防止你的“万一”

 表示空间、抽象空间、AF

表示值构成的空间:实现者看到和使用的值

抽象值构成的空间:client看到和使用的值

ADT开 发者关注表示空间R,client关注抽象空间A

抽象函数:R和A之间映射关系的函数,即如何将R中 的每一个值解释为A中的每一个值。

AF: 满射、非单射、 未必双射 ➔ R中的部分值并非合法的, 在A中无映射值

 以注释的形式撰写AF、RI

表示泄漏的安全声明  给出理由,证明代码并未对外泄露其内部表示——自证清白

ADT的规约里只能使用client可见的内容来撰写,包括参数、返 回值、异常等。

如果规约里 需要提及“值”,只能使用A空间 中的“值”。

ADT的规约里也不应谈及任何内部表示 的细节,以及R空间中的任何值

ADT的内部表示(私有属性)对外部都应严格不可见

故在代码中以注释的形式写出AF和RI而不 能在Javadoc文档中,防止被外部看到而破坏表示独立性/信息隐藏

构造器和生产器在创建对象时要确保不变量为true

变值器和观察器在执 行时必须保持不变性

在每个 方法return之前,用checkRep()检查不变量是否得以保持

第七讲

 接口、抽象类、具体类

通过default方法,在接口 中统一实现某些功能,无需在各个类中重复实现它。

 继承、override

(严格继承:子类只能添加新方法,无法重写超类中 的方法)extends

重写 的函数:完全同样的signature 实际执行时调用哪个方法,运行时决定。

利用super()复用了父类

抽象类不能实例化(不能用new 生成对象)

继承某个抽象类的子类在实例化时,所有父类中的 抽象方法必须已经实现

 多态、overload

特殊多态 一个方法可以有多个同名的实现(方法重载)

▪ 重载:多个方法具有同样的名字,但有不同的参数列表或返回值类型 ▪ 价值:方便client调用,client可用不同的参数列表,调用同样的函数

在编译阶段时决定要具体执行哪个方法

overridden methods则是在run-time进行dynamic checking!

参数化多态 一个类型名字可以代表多个类型(泛型编程)

在运行时根据具体指定类型确定具 体类型(编译成class文件时,会用指定类型替换类型变量“擦除”

子类型多态、包含多态  一个变量名字可以代表多个类的实例(子类型)

不同类型的对象可以统一的处理而无需区分

 泛型

使用泛型变量的三种形式 :泛型类、泛型接口和泛型方法

 Some important Object methods in Java

 等价性equals()和==

如果AF映射到同样的结果,则等价

 equals()的自反、传递、对称

 hashCode()

 不可变对象的引用等价性、对象等价性

 可变对象的观察等价性、行为等价性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值