问题定义:
支持继承的面向对象语言中都不可避免的存在一个问题 - 即对父类做了修改,可能引起子类行为异常。
例子:
父类:
class FragileBaseClass {
private int count = 0;
void inc1(){
//原本父类的行为
count++;
}
void inc2(){
System.out.println("父类 inc2 被调用");
count++;
}
int getCount(){
return this.count;
}
}
子类:
public class FragileSubClass extends FragileBaseClass {
@Override
void inc2(){
System.out.println("子类 inc2 被调用");
inc1();
}
public static void main(String[] args){
FragileSubClass subClass = new FragileSubClass();
subClass.inc2();
System.out.println(subClass.getCount());
}
}
此时运行正常
子类 inc2 被调用
父类 inc1 被调用
1
Process finished with exit code 0
修改父类为:
class FragileBaseClass {
private int count = 0;
void inc1(){
//原本父类的行为
//count++;
//修改后导致子类异常的父类的行为
System.out.println("父类 inc1 被调用");
inc2();
}
void inc2(){
System.out.println("父类 inc2 被调用");
count++;
}
int getCount(){
return this.count;
}
}
此时运行异常:
父类 inc1 被调用
子类 inc2 被调用
父类 inc1 被调用
子类 inc2 被调用
父类 inc1 被调用
子类 inc2 被调用
父类 inc1 被调用
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at FragileSubClass.inc2(FragileSubClass.java:4)
at FragileBaseClass.inc1(FragileBaseClass.java:11)
at FragileSubClass.inc2(FragileSubClass.java:5)
at FragileBaseClass.inc1(FragileBaseClass.java:11)
at FragileSubClass.inc2(FragileSubClass.java:5)
总结:
- 对父类里的方法使用final防止子类继承
- 父类里的动态绑定的方法(即可被子类继承的,运行时决定调用子类还是父类实现的方法)尽量不要修改