ADPoop课后感想

一、数据类型与类型检验
1. 数据类型:基本数据类型/对象数据类型
基本数据类型:只有值,没有 ID;不可变;在栈中分配内存
对象数据类型:有值有 ID;可变+不可变;在堆中分配内存 所有对象类型都直接或间接的继承 Object 类。
基本类型可以通过包装类转换成相应的对象数据类型(通常在容器类使用,
可以自动完成)。
2.类型检验静态:类型检验/动态类型检验
静态类型语言(java)/动态类型语言(python)
静态类型检查:编译阶段,“类型”“格式”的检查
动态类型检查:运行阶段,“值”的检查
//整数除 0 动态类型检查会失败,浮点数除 0 会得到无穷结果。
3.不变性与可变性
改变一个变量:将该变量指向另一个值的存储空间
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值
不变对象:一旦被创建,始终指向同一个值/引用
final:final 类无法派生子类;final 变量无法改变值/引用;final 方法
不能被重写
可变数据可以提高性能,也适合在模块之间共享数据,但也可能会引发潜
在的威胁,所以在使用不可变数据类型时要注意防御式拷贝。
4. Snapshot :用于描述程序运行时的内部状态【会画】
基本类型的值:单线箭头
对象类型的值:单线箭头+椭圆
不可变对象:用双线椭圆
不可变引用:用双线箭头
5.数组和容器类
注意 List 迭代器模式时边遍历边删除可能会引起错误。
6.一些实用的可变数据类型
容器类的不可变包装类,得到的结果只能看,不能修改,如果对其修改,
在编译阶段检查不出来,但运行时会出错。
7.空指针
二、设计规约
1.方法/函数
参数类型、返回值类型是否匹配,都在编译阶段静态检查完成。
规约+实现
2. 规约
规约刻画了编程人员的任务,明确了“供需双方”的责任,使得程序与客户
端达成一致;方便沟通协作;隔离变化。
行为等价性:“两个方法是否等价”,站在客户端视角看行为等价性
规约结构:前置条件(requires,java 为 param)+后置条件(effects,java
为 return)
前置条件:对客户端的约束,使用时必须满足的条件
后置条件:对开发者的约束,方法结束后必须满足的条件
契约精神:前置条件满足后置条件必须满足;前置条件不满足程序可作任何
对于可变方法,除非在后置条件里声明过,否则方法内部不应该修改输入参
数。
3. 设计规约 规约的强度:前置条件更放松后置条件更严格,则规约更强
确定的规约:给定一个满足前置条件的输入,其输出是唯一的、明确的
欠定的规约:同一个输入可以有多个输出
非确定的规约:同一个输入,多次执行得到的输出可能不同
//把欠定的规约和非确定的统称为非确定的规约
操作式规约:比如,伪代码
声明式规约:,没有内部实现的描述,只有“初-终”状态
是否使用前置条件取决于:check 的代价;方法的使用范围。
三、抽象数据类型(ADT)
1.抽象和自定义数据类型
抽象类型:强调“作用在数据上的操作”,程序员和用户无需关注数据如何存
储,只需要设计/使用操作即可。
ADT 是由操作定义的,与其内部如何实现无关。
2.数据类型和操作类型的划分
数据类型:可变/不可变
操作:构造器/生产器/观察器/变值器
构造器(Creator):从无到有
生产器(Producer):从有到新
观察器(Observer):观察值
变值器(Mutator):改变对象属性
3.一些例子
4.设计抽象数据类型
“经验法则”。
简洁、一致的操作;足以便利的支持客户的需要;要么针对抽象设计,要么针
对具体设计,不要混合。
5.表示独立性(Representation Independence)
表示独立性:客户端在使用 ADT 时无需考虑其内部如何实现,ADT 内部表示的
变化不应影响外部规约和客户端。
前置条件和后置条件充分刻画了 ADT 的操作,spec 规定了 client 和
implementer 之间的契约,明确了 client 可以依赖哪些内容,implementer 可
以更安全的更改内容。
6.测试 ADT
7.ADT 的不变量(RI)
不变量:程序在任何时候总要为真的一些性质。
checkRep()检查 RI。
表示泄露(Rep exposure)。
8.抽象函数(Abstraction Function,AF)
表示空间(R):实现者看到和使用的值空间
抽象空间(A):用户看到和使用的值空间
AF 即两者间的映射关系(满射,未必单射,未必双射)
9.有益的可变性 10.以文档的形式写清 AF、RI、Rep exposure
11.用表示不变量代替前置条件
四、面向对象的编程(OOP)
1.基本概念:对象、类、继承和方法
类成员变量、类方法(static)
实例成员变量、实例方法
//静态方法无法直接调用非静态成员
2.接口和枚举类
接口中只有方法的定义,没有实现;接口之间可以继承和扩展;一个类可以实
现多个接口;一个接口可以有多个实现类。
实际中更倾向于用接口定义 ADT。
实现接口的类可以拥有比接口更多的方法,但不能少。
3.封装和信息隐藏
使用接口类型声明变量;客户端仅使用接口中定义的方法;客户端代码无法直
接访问属性。
Public 所有均可见;protected 当前类、同一包内、子孙包均可见,其它包不
可见;default 当前类、同一包内可见;private 仅当前类可见。
4.继承和重写
严格继承:子类只能添加新方法,无法重写父类中的方法(用 final 关键字)
重写:方法拥有完全一致的标签,包括方法名、返回值、参数数目、类型和顺
序,实际调用哪个方法,运行时决定;可见性只能增加不能减少。(@Override)
抽象类:至少含有一个抽象方法;不能实例化;继承抽象类的某个子类在实例
化时,所有父类中的抽象方法必须已经实现。
5.多态、子类型和重载
三种类型的多态:特殊多态、参数化多态和子类型多态
特殊多态:一个方法可以有多个重名的实现(重载)
参数列表必须不同。
根据参数列表进行最佳匹配,在编译阶段决定执行哪个方法
参数化多态:一个类型的名字可以代表多个类型(泛型编程)
泛型变量、泛型类、泛型接口、泛型方法(选学)
//<T>
子类型多态:一个变量名字可以代表多个类的实例(子类型)
子类型规约不能弱化父类型的规约。
一定注意 equals()方法里的参数是 Object.
//public Boolean equals(Object o){…}
五、ADT 和 OOP 中的等价性
1.等价关系
自反、对称、传递
2.三种看待等价性的方式
(1).基于抽象函数 AF 定义 ADT 的等价操作
A 和 b 等价当且仅当 AF(a)=AF(b),即映射到相同的结果。
(2).站在观察者角度 对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是
等价的。
3.==和 equals()
4.Object contract
5.可变类型的等价性
观察者等价性、行为等价性
//倾向于实现严格的观察者等价性
//对可变类型来说,死刑案行为等价性即可,即指向相同的内存空间,才是相
等的。
//总结:不可变类型一定要重写 equals()和 hashCode(),可变类型一般不需要
6.包装类和等价性
“-128-127”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值