在面向对象编程中,子类继承父类是很常见的做法,但是,在使用继承的过程中,如果父类被修改了的话,很有可能会导致子类出现一些问题.
1.父类增加了新的方法,导致和子类的行为无法预测
例如,有2个类
class A{
private int i = 0;
public void a(){
System.out.println(i);
}
}
class B extend A{
public void b(){
System.out.println(i);
}
}
之后,父类A增加了一个方法b
class A{
private int i = 0;
public void a(){
b();
System.out.println(i);
}
public void b(){
i++;
}
}
在A类修改之后B类执行方法A时,行为可能完全超乎预期.
2.父类修改了方法的内容导致死循环
class Super {
private int counter = 0;
void inc1() {
counter++;
}
void inc2() {
counter++;
}
}
class Sub extends Super {
@Override
void inc2() {
inc1();
}
}
父类修改之后
class Super {
private int counter = 0;
void inc1() {
inc2();
}
void inc2() {
counter++;
}
}
这个时候子类调用覆盖的inc2()方法后,会出现一个无限递归的情况,最后系统会以stack over flow 来终结.
一些解决方案
在java中,因为override注解不是强制的,所以fragile base class问题只能通过规范来解决,就是尽量使用接口,不要依赖父类的实现.
在scala中,因为override是一个修饰符,子类的函数如果没有继承父类,那么加override会编译报错,反之,子类继承的函数,必须加override修饰符,这是一个很好的方式,因为编译错误,总比在运行时行为混乱要好的多.