6 Abstract Data Type (ADT)
ADT:抽象数据类型
ADT的特性:表示泄漏、抽象函数AF、表示不变量RI
Creators:构造器
Producers:生产器
Observers:观察器
Mutators:变值器
不可变数据类型没有变值器
重点:
String类型:
creators: String constructors
producers: concat , substring , toUpperCase
observers: length , charAt
mutators: none
List类型:
creators: ArrayList andLinkedList constructors,Collections.singletonList
producers:Collections.unmodifiableList
observers: size , get
mutators: add , remove , addAll ,Collections.sort
表示独立性:用户使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部规约和客户端。除非ADT的操作指明了具体的前置条件和后置条件,否则不能改变ADT的内部表
不变性:在程序运行中程序始终保持不变,例如immutability就是一个典型的”不变量“,在任何时候都表现为相同的值。ADT有责任来保持其不变性而非依赖于用户和其他模块。
不变量在任何时候都是true。
表示泄露:不仅影响不变性,也影响了表示独立性:无法在不影响客户端的情况下改变其内部表示
避免泄露的方法:
(1)将public修改为private/ final
(2)返回时防御式拷贝
(3)返回时使用Collections.unmodifiableSet()
RI:表示不变性 AF:抽象方法
R:表示空间,包括实际实现时的值。
A:抽象空间,包括用户看到和使用的值。
ADT开发者关注表示空间R,而用户关注抽象空间A。
从R空间到A空间的映射是满射,但未必是单射,也未必是双射。
抽象函数:R和A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值。
表示不变性RI:某个具体的“表示”是否是“合法的”
也可将RI看作:所有表示值的一个子集,包含了所有合法的表示值或者一个条件,描述了什么是“合法”的表示值
例子:
由题意,s的长度为偶数因此tvv和tuv被干掉了,AF的含义是是s[2i]->s[2i+1]之间的所有字母
因此2和3是正确的,{t,u,v}
7 Object-Oriented Programming (OOP)
静态/实例方法:
在类中使用static修饰的静态方法会随着类的定义而被分配和装载入内存中;而非静态方法属于对象的具体实例,只有在类的对象创建时在对象的内存中才有这个方法的代码段
编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然可能有多个实例,但这些实例共享该内存
Interface和Class: 定义和实现ADT
接口之间可以继承与扩展
一个类可以实现多个接口(从而具备了多个接口中的方法)
一个接口可以有多种实现类
重写:
严格继承:子类只能添加新方法,无法重写超类中的方法
如果一个java中方法不能被重写,必须要加上前缀final
对某些子类型来说,有特殊性,故重写父类型中的函数,实现自己的特殊要求
重写时,不应该改变方法的本意
多态:
类型:特殊多态(重载),参数化多态,子类型多态
重载: 多个方法具有同样的名字,但有不同的参数列表或返回值类型
优势: 方便用户调用,用户可用不同的参数列表,调用同样的函数
重载是一种静态多态,根据参数列表进行”最佳匹配”,在build-time 编译过程进行静态类型检查,重写则是
在run-time进行dynamic checking
要点:
1)参数列表必须不同
2)相同/不同的返回值类型
3)相同/不同的public/private/protected
4)可以声明新的异常
重写和重载对比
重载参数发生了改变
泛型擦除:运行时泛型类型消除(如:List<String>运行时是不知道String的),所以,不能使用泛型数组
重写时,子类的规约要强于父类的规约(更弱的前置条件,更强的后置条件)
子类的可见性要强于父类(即父类如果是public,子类不能为private)
子类不能比父类抛出更多的异常
子类型多态:不同类型的对象可以统一的处理而无需区分
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/267083.html