软件构造第四章-第七章总结

一. 基本数据类型/对象数据类型

静态/动态类型检查

(Java是静态类型检查,在编译阶段进行检查,Java不进行动态类型检测)

静态类型检查:语法、类名/函数名、参数数目、参数类型、返回值类型

动态类型检查:非法的参数值、非法的返回值、越界、空指针

List<String>和List<Object>是在静态类型检测中报错。

Mutable/Immutable

 Immutable好处:安全,但浪费空间。

使用Mutable可获得更好的性能,也适合多个模块间共享数据,但不够安全

Date也是mutable类!避免使用!

可以使用java.time包中的其他immutable类型的类:LocalDateTime, Instant等

immutable拷贝时间 O(n2)

传参数尽量用immutable类型(保证参数不变性),如果传mutable参数可先进行defensive copying

必须通过类中的方法来改变类中的属性(防止信息泄露)

*Snapshot diagram

Immutable对象:用双线椭圆

不可变的引用(用final修饰的变量):用双线箭头

Array and Collections

Iterator
mutable类型,有两种方法:next()和hasNext(),next()方法是mutate的

需要注意,当用Iterator迭代List中元素,涉及到remove时,由于remove后List内元素索引会发生改变,会出现错误。

Collections
基本类型及其封装对象类型都是immutable的

List、Map、ArrayList等都是mutable的

可以利用Collections类提供的方法将mutable类包装成immutable

Collections.unmodifiableList Collections.unmodifiableSet Collections.unmodifiableMap

这种”不可变“是在运行阶段获得的,编译阶段无法对此进行静态检查
虽然不能用包装后的对象对其进行修改,但依旧能用包装前的对象进行修改


二. 设计规约

规约注释包含:功能描述、输入数据限制、返回值

行为等价性(Behavioral equivalence)
一般站在用户(客户端)的角度看可根据规约判断是否行为等价

前置条件和后置条件
前置条件,关键词requires 后置条件,关键词effects

前置条件是对客户端的约束,在使用方法时必须满足的条件;后置条件是对开发者的约束,方法结束时必须满足的条件

如果前置条件满足,后置条件必须满足;如果前置条件不满足,后置条件想淦神魔都可以

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

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

前置条件在 @param中,后置条件在 @return和@throws中(@return中不能包含具体类型,如 @return boolean)

如果方法对输入的参数做了改变,一定要在规约中说明

*规约的强弱(本节重点)
判定标准
规约强度 S2 >= S1 : 前置条件更弱,后置条件更强

spec变强,即更放松的前置条件 + 更严格的后置条件

Diagramming specifications
每一个点代表一个方法的实现。如果某个具体实现满足规约,就落在其范围内;否则在其之外。

更强的规约,表示为更小的区域。(实现的自由度小,面积小)

三. 抽象数据类型(ADT)

ADT 的特性:表示泄漏、抽象函数 AF 、表示不变量 RI

基于数学的形式对 ADT 的这些核心特征进行描述并应用于设计中

ADT是由操作定义的,与其内部实现无关

ADT四种操作类型

构造器(Creator):创建一个该类型的新对象(可能实现为构造函数或静态函数)
生产器(Producer):从一个类型的旧对象创建一个新对象(如String中concat方法)
观察器(Observer):返回一个不同类型的对象(如List中的size方法)
变值器(Mutator):改变对象属性的方法(如List中的add方法)


如果一个构造器是用静态方法来实现的,通常称为工厂方法 (factory method):如Java中String类的String.valueOf(Object obj)方法

Mutators通常返回void,但也可以返回非空类型,如Set.add()返回的类型为boolean

immutable类型的ADT无变值器(Mutator)

判断是哪种操作类型,首先需要确定是mutable还是immutable

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

上述实例就违反了表示独立性,因为public限定了这是一个instance variable,但是后面的final又限定了客户端不能够实际改变这个类的immutability属性

表示泄露出现情况:

public 类型的数据 -> private final
mutable 类型共享引用
不应该包含mutate方法

*Rep Invariant and Abstraction Function(RI and AF)

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

R -> A 的映射:1. 满射:所有抽象值都要有一个rep value 2. 未必单射:一个抽象值可能有多个表示 3. 未必双射:不是所有的表示值都有对应的抽象值

抽象函数(AF):R和A之间映射关系的函数

表示不变性 RI:某个具体的“表示”是否是“合法的”(R -> boolean)

在ADT的规约里若出现"值",也只能是A空间的"值"

四. 面向对象的编程(OOP)

静态/实例方法

在类中使用static修饰的静态方法会随着类的定义而被分配和装载入内存中;而非静态方法属于对象的具体实例,只有在类的对象创建时在对象的内存中才有这个方法的代码段

编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然可能有多个实例,但这些实例共享该内存

接口(Interface)

接口之间可以继承与扩展,一个类可以实现多个接口,一个接口可以有多种实现类

接口:确定ADT规约; 类:实现ADT

Java的接口中不能含有constructors,但是从Java 8开始接口中可以含有static工厂方法,可用其替代constructors

default
通过default方法,可以在接口中统一实现某些功能,无需在各个类中重复实现它。好处是以增量式为接口增加额外的功能而不破坏已经实现的类

重写(Overriding)

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

如果想要一个java中方法不能被重写,必须要加上前缀final

父类型中的被重写函数体不为空:意味着对其大多数子类型来说,该方法是可以被直接复用的。对某些子类型来说,有特殊性,故重写父类型中的函数,实现自己的特殊要求
如果父类型中的某个函数实现体为空,意味着其所有子类型都需要这个功能,但各有差异,没有共性,在每个子类中均需要重写
重写时,可以利用super()来复用父类型中函数的功能


抽象类(Abstract Class)

抽象方法:只有声明没有具体实现的方法。用关键词abstract来定义

抽象类:如果一个类含有至少一个抽象方法,则被称为抽象类

接口:一个只含有抽象方法的抽象类

如果某些操作是子类型都共有,但彼此有差别,可以在父类型中设计抽象方法,在各子类型中重写

接口和抽象类都不能实例化!

多态的三种类型
特殊多态(Ad hoc polymorphism):重载
参数化多态(Parametric polymorphism):泛型
子类型多态、包含多态(Subtyping):继承
特殊多态和重载(Overloading)
重载:多个方法具有同样的名字,但有不同的参数列表或返回值类型

重载是一种静态多态,根据参数列表进行"最佳匹配",进行静态类型检查

重载的解析在编译阶段,与之相反,重写的方法是在运行阶段进行动态类型检查

参数列表必须不同
相同/不同的返回值类型
相同/不同的public/private/protected
可以声明新的异常
Overloading和Overriding的对比


参数多态和泛型(Generic)

通配符(Wildcards),只在使用泛型的时候出现,不能在定义中出现。 如:List< ? extends Animal >

?extends T 和 ?super T 分别表示T和它的所有子/父类

子类型多态、继承
重写时,子类的规约要强于父类的规约(更弱的前置条件,更强的后置条件)
子类的可见性要强于父类(即父类如果是public,子类不能为private)
子类不能比父类抛出更多的异常

子类型多态:不同类型的对象可以统一的处理而无需区分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值