C#中的父類與子類的繼承關係與C和C++中的類似,這裡先闡述最重要的一點:假如子類繼承了父類,那麼子類可以強制轉換為父類,並且保證編譯和運行都不出錯;但是父類強制轉換成子類的時候,編譯可以通過運行通不過。請看如下代碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace FatherAndSon{ class ClassA { static void Main(string[] args) { //編譯和運行都能通過 ClassB b = new ClassB(); ClassA a = (ClassA)b; //編譯能通過,運行通不過 ClassA aa = new ClassA(); ClassB bb = (ClassB)aa; } } class ClassB : ClassA { }}
實際上:將子類強制轉換為父類之後,在用這個父類強制轉換為另外一個子類的時候編譯和運行也都能通過;只是如果將父類直接轉換為子類的時候運行會出錯。這就好比:假設父類是一個裝了5個“蘋果”的“小型籃子”,而子類則是一個裝了5個“蘋果”和5個”西瓜“的大型籃子;將子類強制轉換為父類<=>把父類的”小型籃子“換成”大型籃子“,但還是只裝5個”蘋果“(將父類的引用指向子類,但父類只能調用父子自身的變數和方法),之後再用這個父類強制轉換為另外一個子類<=>向”大型籃子“裡面裝入5個”西瓜“送給子類的引用;而將父類直接轉換為子類<=>用父類的”小型籃子“裝”5個蘋果和5個西瓜“送給子類的引用(當然是裝不下)請看如下代碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace FatherAndSon{ class ClassC { static void Main(string[] args) { //先將子類強制轉換為父類,然後用此父類強制轉換為另外一個子類(通過) ClassB b = new ClassB(); ClassA a = (ClassA)b; ClassB bbbbb = (ClassB)a; //(將父類直接強制轉換為子類)編譯能通過,運行通不過 ClassA aa = new ClassA(); ClassB bb = (ClassB)aa; } } class ClassA { } class ClassB : ClassA { }}
另外一個值得非常注意的地方是:無論是子類強制轉換賦給父類,還是父類(由子類強轉得到)強制轉換為子類;類對象是根據聲明的類型(子類或父類)去調用其變數和函數的,與賦值無關。請看如下代碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace FatherAndSon{ class ClassC { static void Main(string[] args) { //先將子類強制轉換為父類,然後用此父類強制轉換為另外子類(通過) ClassB b = new ClassB(); b.PrintFunc(); Console.WriteLine(b.myStr); ClassA a = (ClassA)b; a.PrintFunc(); Console.WriteLine(a.myStr); ClassB bbbbb = (ClassB)a; bbbbb.PrintFunc(); Console.WriteLine(bbbbb.myStr); //(將父類直接強制轉換為子類)編譯能通過,運行通不過 //ClassA aa = new ClassA(); //ClassB bb = (ClassB)aa; //bb.PrintFunc(); } } class ClassA { public string myStr; public ClassA() { myStr = "Hello, This is myStr in ClassA"; } public void PrintFunc() { Console.WriteLine("This is the Print Function in ClassA"); } } class ClassB : ClassA { public string myStr; public ClassB() { myStr = "Hello, This is myStr in ClassB"; } public void PrintFunc() { Console.WriteLine("This is the Print Function in ClassB"); } }}
上面代碼輸出的結果為:
This is the Print Function in ClassB
Hello, This is myStr in ClassB
This is the Print Function in ClassA
Hello, This is myStr in ClassA
This is the Print Function in ClassB
Hello, This is myStr in ClassB
可以看出:類的執行個體對象在調用其變數和方法時,確實是以 聲明 成為的類為依據的。