OO中的继承性的思考和说明
1.继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然他不强制要求所有的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏2.继承在给程序设计带来便利的同时,也带来了弊端,比如使用继承会给程序带来入侵性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所涉及到子类的功能都有可能产生故障3.问题提出:在编程中如何正确使用继承?=>里氏替换原则
所有引用基类的地方必须能透明的使用其子类的对象
在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
继承实际上让两个类耦合性增强了,在适当情况下,可以通过聚合,组合,依赖来解决问题
package com.cedric.principle.liskov;
// 程序误写产生的问题
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println(a.fun1(20, 10));
B b = new B();
System.out.println(b.fun1(20,10)); // 这里本意是求20 - 10
System.out.println(b.fun2(20,10));
}
}
class A{
// 返回两个数的差
public int fun1(int num1,int num2){
return num1 - num2;
}
}
// B继承A,新增一个功能:完成两数相加,然后和9求和
class B extends A{
// 这里重写了A类的方法,可能是无意识的
public int fun1(int a,int b){
return a + b;
}
public int fun2(int a,int b){
return fun1(a,b) + 9;
}
}
改进方案
代码实现:
package com.cedric.principle.liskov.improve;
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println(a.fun1(20, 10));
System.out.println("============================");
B b = new B();
// 因为B类不再继承A类,因此调用者不会再是fun1求减法
// 调用完成的功能就会很明确
System.out.println(b.fun1(20,10)); // 这里本意是求20 + 10
System.out.println(b.fun1(10,10)); //10 + 10
// 使用组合仍然可以使用到A类相关的方法
System.out.println(b.fun3(30,20)); // 本意是求出30 - 20
}
}
// 创建一个更加基础的基类
class Base{
// 把更加基础的方法和成员写到Base类
}
class A extends Base{
// 返回两个数的差
public int fun1(int num1,int num2){
return num1 - num2;
}
}
// B继承A,新增一个功能:完成两数相加,然后和9求和
class B extends Base{
private A a = new A();
// 这里重写了A类的方法,可能是无意识的
public int fun1(int a,int b){
return a + b;
}
public int fun2(int a,int b){
return fun1(a,b) + 9;
}
public int fun3(int a,int b){
return this.a.fun1(a,b);
}
}
