oo中的繼承性的思考和說明
1、繼承包含這樣一層含義:父類中凡是已經實作好的方法,實際上是在設定規范和契約,雖然它不強制要求所有的子類必須遵循這些七月,但是如果子類對這些已經實作的方法任意修改,就會對整個繼承體系造成破壞,
2、繼承在給程式設計帶來便利的同時,也帶來了弊端,比如使用繼承會給程式帶來侵入性,程式的可移植性降低,增加物件間的耦合性,如果一個類被其他的類所繼承,則當這個類需要修改時,必須考慮到所有的子類,并且父類修改后,所有涉及到子類的功能都有可能產生故障,
3、問題提出:在編程中,如何正確的使用繼承? 答:盡可能遵循里氏替換原則,
基本介紹
1、里氏替換原則在1988年,由麻省理工學院的一位姓里的女士提出的,
2、如果對每個型別為T1的物件o1,都有型別為T2的物件o2,使得T1定義的所有程式p在所有的物件o1都代換成o2是,程式p的行為沒有發生變化,那么型別T2是型別T1的子型別,換句話說,所有,所有應用型別的地方必須能透明地使用其子類的物件,
3、在使用繼承時,遵循里氏替換原則,在子類中盡量不要重寫父類的方法,
4、里氏替換原則告訴我們,繼承實際上讓兩個類耦合性增強了,在適當的情況下,可以通過聚合,組合,依賴來解決問題,
應用案例
沒有使用里氏替換原則
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("--------------------");
B b = new B();
System.out.println("11-3=" + b.func1(11, 3));
System.out.println("1-8=" + b.func1(1, 8));
System.out.println("11+3+9=" + b.func3(11, 3));
}
}
class A {
// 兩個數的差
public int func1(int num1, int num2) {
return num1 - num2;
}
// 兩個數的積
public int funcBase(int num1, int num2) {
return num1 * num2;
}
}
//B類繼承了A
//增加了一個新功能,完成兩個數相加,然后和9求和
class B extends A {
// 這里,重寫了A的方法,可能是無意識
public int func1(int a, int b) {
return a + b;
}
public int func3(int a, int b) {
return func1(a, b) + 9;
}
}
使用里氏替換原則
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("--------------------");
B b = new B();
System.out.println("11-3=" + b.func1(11, 3));
System.out.println("1-8=" + b.func1(1, 8));
System.out.println("11+3+9=" + b.func2(11, 3));
// 使用組合來使用A的相關方法
System.out.println("--------------------");
System.out.println("11-3=" + b.func3(11, 3));
System.out.println("1-8=" + b.func3(1, 8));
System.out.println("11+3+9=" + b.func2(11, 3));
}
}
class Base {
// 把更加基礎的方法和成員寫到Base類
// 兩個數的積
public int funcBase(int num1, int num2) {
return num1*num2;
}
}
class A extends Base {
// 兩個數的差
public int func1(int num1, int num2) {
return num1 - num2;
}
}
//B類繼承了A
//增加了一個新功能,完成兩個數相加,然后和9求和
class B extends Base {
// 如果B需要使用A類得方法,使用組合關系
private A a = new A();
// 這里,重寫了A的方法,可能是無意識
public int func1(int a, int b) {
return a + b;
}
public int func2(int a, int b) {
return func1(a, b) + 9;
}
// 使用A得方法
public int func3(int a, int b) {
return this.a.func1(a, b);
}
}
上面這段代碼中,使用了里氏替換原則,將更基礎的方法funcBase()提取出來,然后將A類和B類繼承這個更基礎的Base類,采用依賴、聚合或耦合的方式來減少父類和子類的耦合
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/29315.html
標籤:設計模式
上一篇:面向物件的六大原則
