OOP
1. Interface
接口
接口的成员变量默认用final关键字修饰,故必须有初值,可用public,default修饰,可用static修饰。
接口的方法只能被public、default、abstract、static、strictfp(严格浮点运算)修饰。
Interface和Class: 定义和实现ADT – 接口中只有方法的定义,没有实现 – 接口之间可以继承与扩展 – 一个类可以实现多个接口(从而具备了多个接口中的方法) – 一个接口可以有多种实现类
1. Inheritance、override 继承和重写
Strict
inheritance 严格继承:子类只能添加新方法,无法重写超类(父类)中的方法(final限制)。
考虑final修饰类、方法、属性时的不同作用。
Override
方法:具有一致的signature,复用的基本机制。
父类型中的被重写函数体不为空:意 味着对其大多数子类型来说,该方法 是可以被直接复用的。
如果父类型中的某个函数实现体为空, 意味着其所有子类型都需要这个功能, 但各有差异,没有共性,在每个子类中 均需要重写。
、抽象类:只有定义没有实现,由关键字abstract定义,抽象类不能实例化(不能用new 生成对象),继承某个抽象类的子类在实例化时,所有父类中的 抽象方法必须已经实现
1. Polymorphism
,subtyping
and overloading 多态,子类型化,重载
三种多态:
1. Ad
hoc polymorphism (特殊多态)
用于function
overloading(功能重载),即重载
一个方法可以有多个同名的实现(方法重载)
2. Parametric
polymorphism (参数化多态)
泛型
一个类型名字可以代表多个类型(泛型编程)
3. Subtyping
(subtype polymorphism / inclusion
polymorphism )(子类型多态、包含多态)
一个变量名字可以代表多个类的实例(子类型)
1.
Overloading 重载
1.
重载条件:
1.
方法名相同
2.
参数列表不同,即参数类型、个数、类型顺序至少有一项不相同
3.
返回值类型可以不同
4.
方法的修饰符可以不同
5.
可以抛出不同的异常
6.
可以在类内重载,也可以在子类重载
2.
重载是一种静态多态,静态类型检查
(static dispatch 静态分派)并在编译阶段决定具体执行哪个方法(即对方法的调用取决于编译时声明的引用的类型)
而重写(dynamic dispatch 动态分派)则进行动态类型检查,根据运行时堆中的实例类型选择方法。
重写时父类和子类中的方法具有相同的签名,签名不同时则为重载,子类重载了父类的 方法后,子类仍然继承了被重载的方法
2.
Generic 泛型
使用泛型变量的三种形式:泛型 类、泛型接口和泛型方法
1.
通配符
2.
类型擦除:编译后、运行时类型擦除
List
-> List
注意可能引起重载编译错误。
运行时不能用 instanceof 检查泛型。
3.
不能创建泛型数组
不能用在静态变量
不能创建对象(不能new)
3.
Subtypes
超类的子类型,如:ArrayList和LinkedList是List的子类型。
子类型的规约不能弱化超类型的规约。
1.
子类型多态:不同类型的对象可以统一处理而无需区分(不加区分地调用同样的方法等),从而隔离变化
2.
LSP(Liskov Substitution Principle) 如果S是T的子类型,那么T的对象可以被S的对象替换。
3.
Type casting 类型转换
避免向下类型转换。
4.
Dispatch 分派
Static dispatch 静态分派
Dynamic dispatch 动态分派
将调用的名字与实际方法的名字联系起来(可能有多个)
决定具体执行哪一个操作
重载,在编译阶段即可确定执行哪个具体操作
重写,在运行时决定
Early/static binding
Lade/dynamic binding
绑定static、private、final方法时发生
重写父类子类的同样方法
1. equals()
1.
引用等价性
比较内存地址ID
用于比较基本数据类型
2.
对象等价性
equals()
验证正确性:reflexive 自反性、symmetric 对称性、transitive 传递性、非空(a.equals(null) return false)
对基本数据类型,使用==判定相等
对对象类型,使用equals()
如果用==,是在判断两个对象身份 标识
ID是否相等(指向内存里的同一段空间)
hashCode()
等价的对象必须有相同的hashCode
Rule:重写equals时重写hashcode
1.
1. Equality
of Mutable Types 可变对象的等价性
Observational
equality 观察等价性
Behavioral equality
行为等价性
在不改变状态的形况下,两个mutable看起来是否一致
调用对象的任何方法都展示出一致的结果
调用observer,producer,creator
调用任何方法,包括mutator
当前情况下,看起来(如成员变量)相同
经过改变后,依然相同(只是别名引用)
对不可变类型,观察等价性和行为等价性完全等价。
对可变类型,往往倾向于实现严格的观察等价性。(但有时观察等价性可能导致bug,甚至破坏RI)
对可变类型,应当实现行为等价性,即只有指向内从空间中同样的objects才相等(即equals比较引用,如==而hashcode把引用映射为一个值)。
所以对可变类型,无需重写equals和hashcode,直接继承object。(比较引用)
若一定要判断两个可变对象是否一致,最好定义一个新的方法。