繼承&里氏轉換(LSP)
1. 繼承複習
解決代碼的冗餘,實現多形(多態),增加了代碼的擴展素,便於維護。
繼承有兩個很重要的特性:
- 單根性
- 傳遞性
單根性
單根性指的是,一個類只能有一個父類,所以我們說,類是單繼承的,誰是多繼承的?介面(接口),介面才能多繼承。
類別:單繼承;介面:多繼承
傳遞性
- 子類可以使用父類的成員,一個類繼承了一個父類,繼承了屬性和方法,沒有繼承Field(欄位/字段)。
- 子類並沒有繼承父類的構造函數,而是會默認調用父類的那個無參數的構造函數。
- 如果一個子類繼承了一個父類,那麼這個子類除了可以使用自己的成員外,還可以使用從父類那邊繼承過來的成員。但是父類永都只能使用自己的成員,而不能使用子類的成員。子類之間也不能互相使用對方的成員。
2. 里氏轉換(LSP)
里氏轉換(LSP)就兩條定義:
- 子類可以賦值給父類
- 父類強轉為子類。(前提是這個父類裡面裝的一定是子類對象) 如果父類中裝的是子類對象(物件),那麼可以將個父類轉換為子類對象(物件)
- 用
as、is兩個關鍵字做轉換as:轉換成功返回對應的對象(物件),轉換失敗返回nullis:is會用在判斷,轉換成功回傳true,失敗回傳false
里氏轉換
里氏轉換(LSP)就兩條定義:
- 子類可以賦值給父類
- 父類強轉為子類
里氏轉換(LSP)第一條:子類可以賦值給父類
1
2
3
4
5
6
7
8
9
10
11
//子類可以賦值給父類
Person person = new Student();
//父類
public class Person {
}
//子類
public class Student : Person {
}
public class Teacher : Person {
}
里氏轉換(LSP)第二條:將父類強轉為子類
(前提是這個父類裡面裝的一定是子類對象)
如果父類中裝的是子類對象(物件),那麼可以將個父類轉換為子類對象(物件)
1
2
3
4
5
6
7
8
9
10
11
12
//子類賦值給父類
Person person = new Student();
//父類強轉為子類對象
Student s = (Student)person;
//報錯,不能轉為Teacher對象,
//因為person裡面裝的是Student對象,轉不過來呀
//Teacher t = (Teacher)person;
Console.WriteLine(s.ID);
Console.ReadKey();
as is強制轉型
用as、is兩個關鍵字做轉換
as
as它的使用規則是,轉換成功返回對應的對象(物件),轉換失敗返回null
- 轉換成功:返回對應的對象(物件)
- 轉換失敗:返回
null
1
2
Student s = person as Student; //可以轉,返回對應的對象
//Teacher t = person as Teacher; //不能轉,返回null
is
is會用在判斷,轉換成功回傳true,失敗回傳false
1
2
3
4
5
6
7
8
//子類可以賦值給父類
Person person = new Student();
//is會用在判斷,轉換成功回傳true,失敗回傳false
if (person is Student) {
Console.WriteLine("OK,可以轉換");
} else {
Console.WriteLine("NO,不可以轉換");
}
繼承補充
如果一個子類繼承了一個父類,那麼這個子類除了可以使用自己的成員外,還可以使用從父類那邊繼承過來的成員。但是父類永都只能使用自己的成員,而不能使用子類的成員。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//子類可以賦值給父類
Person person = new Student();
//父類
public class Person {
public string Name { get; set; }
}
//子類
public class Student : Person {
public int ID { get; set; }
}
public class Teacher : Person {
public decimal Salary { get; set; }
}
現在person裡面表現出來的是父類類型,但實際上裡面裝的是子類對象(物件)Student()類型。
如果兩個類之間有繼承關係的話,此類可以使用自己的成員,也可以使用從父類繼承過來的成員。但是父類只能使用自己的成員。
不管你裡面裝的到底是什麼樣類型的對象(物件),只要你表現的類型是父類的,那麼你.點的只能是自己的成員。
比如說,Person裡面有那麼一個東西:一個屬性,對於這兩個子類對象(物件)Student、Teacher都可以調用父類這個屬性,那麼在子類當中都有一個屬於自己的屬性,他們各自的屬性,只能自己調用自己,不能互調。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//如果一個子類繼承了一個父類,那麼這個子類除了可以使用自己的成員外,還可以使用從父類那邊繼承過來的成員。
//但是父類永都只能使用自己的成員,而不能使用子類的成員。
//子類之間也不能互相使用對方的成員。
//父類永都只能使用自己的成員,而不能使用子類的成員。
Person person = new Student();//子類可以賦值給父類
person.Name = "Rii"; //類型是父類,只能點的只能是自己父類的成員Name
//子類可以使用父類成員和自己的成員
//子類之間不能互相使用對方的成員。
Student student = new Student();
student.ID = 1001; //Student自己的成員ID
student.Name = "Rii";//從父類繼承過來的Name成員
//student.Salary 不能互調Teacher的成員
Teacher teacher = new Teacher();
teacher.Salary = 5000; //子類teacher自己的成員Salary
teacher.Name = "Kii";//從父類繼承過來的Name成員
//teacher.ID 不能互調Student的成員
結論,如果一個子類繼承了一個父類,那麼這個子類除了可以使用自己的成員外,還可以使用從父類那邊繼承過來的成員。但是父類永都只能使用自己的成員,而不能使用子類的成員。子類之間也不能互相使用對方的成員。