9 Extends, Casting, Higher Order Functions
自己用来复习的
cs61B版本,老师讲的对我来说有点快,边听边记笔记实在太难了
Extend
这里提到了私有的方法无法被继承调用,注意一下就好
接下来是@Override,表示覆盖父类的方法
super.表示引用父类的成分,和this.使用方式类似(calls Superclass’sversion of removeLast())
@Override
public Item removeLast() {
Item oldBack = super.removeLast();
deletedItems.addLast(oldBack);
return oldBack;
}
另外多说一句,super.super是不被允许的,因为绕过了父类,违反封装(https://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java)
构造方法(constructor)是和类同名的方法。
在继承中,构造方法必须以super的调用开始,就算不写,依然会回到父类的构造方法
public VengefulSLList() {
super();
deletedItems = new SLList<Item>();
}
为什么右边的程序错了呢?因为如果不写明super(x) 其中有参数x 那么默认调用的 就是无参数的构造函数,就会出错,这一点很重要
继承是is-a而不是has-a
封装(Encapsulation)
不需要知道底层原理,可以使用一些方法
继承可能破坏封装
这直接导致了一种死循环,因为继承的实现打破了封装,改变了bark的实现,死循环了(这里没听懂,个人理解)
Implementation Inheritance Breaks Encapsulation
casting
public static void main(String[] args) {
VengefulSLList<Integer> vsl =
new VengefulSLList<Integer>(9);
SLList<Integer> sl = vsl;
sl.addLast(50); //因为没覆写,所以使用slist的
sl.removeLast(); //覆写了,使用vs1的
sl.printLostItems();//错误,尽管vs1有,但是s1中没有,所以报错
VengefulSLList<Integer> vsl2 = sl; //错误,也不能这种赋值
}
编译器还允许基于编译时类型进行赋值。
编译器通过类型检查尽可能安全地运行它。(所谓的保守)
Poodle frank = new Poodle("Frank", 5);
Poodle frankJr = new Poodle("Frank Jr.", 15);
Dog largerDog = maxDog(frank, frankJr);//正常运行
Poodle largerPoodle = maxDog(frank, frankJr);//运行错误
高阶函数
python
def tenX(x):
return 10*x
def do_twice(f, x):
return f(f(x))
print(do_twice(tenX, 2))
Java
public interface IntUnaryFunction {
int apply(int x);
}
public class TenX implements IntUnaryFunction {
public int apply(int x) {
return 10 * x;
}
}
public class HoFDemo {
public static int do_twice(IntUnaryFunction f, int x) {
return f.apply(f.apply(x));
}
public static void main(String[] args) {
System.out.println(do_twice(new TenX(), 2));
}
}
VengefulSLList extends SLList means a VenglefulSLList is-an SLList. Inherits all members!
Variables, methods, nested classes.
Not constructors.
Subclass constructor must invoke superclass constructor first.
Use super to invoke overridden superclass methods and constructors.
Invocation of overridden methods follows two simple rules:
Compiler plays it safe and only lets us do things allowed by static type.
For overridden methods the actual method invoked is based on dynamic type of invoking expression, e.g. Dog.maxDog(d1, d2).bark();
r overridden methods the actual method invoked is based on dynamic type of invoking expression, e.g. Dog.maxDog(d1, d2).bark();
Can use casting to overrule compiler type checking.