關於C 繼承與多型的思考

2021-09-17 04:29:18 字數 4073 閱讀 3395

在網上看到了一句話:繼承是子類使用父類的方法,而多型則是父類使用子類的方法。
我覺得這句話說的還是蠻不錯的

c#中的繼承符合下列規則:

1、繼承是可傳遞的。如果c從b中派生,b又從a中派生,那麼c不僅繼承了b中宣告的成員,同樣也繼承了a中的成員。object 類作為所有類的基類。

2、派生類(子類)應當是對基類(父類)的擴充套件。派生類可以新增新的成員,但不能除去已經繼承的成員的定義。

3、建構函式和析構函式不能被繼承。除此以外的其它成員,不論對它們定義了怎樣的訪問方式,都能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。

4、派生類如果定義了與繼承而來的成員同名的新成員,就可以覆蓋已繼承的成員。但這並不因為這派生類刪除了這些成員,只是不能再訪問這些成員。

5、類可以定義虛方法、虛屬性以及虛索引指示器,它的派生類能夠過載這些成員,從而實現類可以展示出多型性。

6、派生類只能從乙個類中繼承,可以通過介面實現多重繼承。

using system;

public class parentclass

public void print( )

}public class childclass : parentclass

public static void main( )

}

這段**執行後的輸出就會是這樣的:

父類建構函式

子類建構函式

i'm a parent class

正如前面所說的,子類會繼承父類除了建構函式和析構函式以外的所有屬性(方法以及變數)

然後就是關於通過 base 關鍵字訪問基類的成員:
base關鍵字的作用如下:

1.呼叫基類上已被其他方法重寫的方法。

2.指定建立派生類例項時應呼叫的基類建構函式。

3.基類訪問只能在建構函式、例項方法或例項屬性訪問器中進行。

最後注意一點:

從靜態方法中使用 base 關鍵字是錯誤的!!
例項**如下:

using system ;

public class parent

public parent(string mystring)

public void print( )

}public class child : parent

public void print( )

public static void main( )

}

程式執行輸出:

from derived

child constructor.

i'm a parent class.

i'm a child class.

i'm a parent class.

其中:

((parent)child).print( );
這段**與在子類中定義的這段**

base.print( ) ;
是一樣的效果,只是前者可在類外進行強制轉換輸出,後者必須定義在子類的方法之中。

想想看,如果所有的類都可以被繼承,繼承的濫用會帶來什麼後果?類的層次結構體系將變得十分龐,大類之間的關係雜亂無章,對類的理解和使用都會變得十分困難。有時候,我們並不希望自己編寫的類被繼承。另一些時候,有的類已經沒有再被繼承的必要。c#提出了乙個

密封類(sealed class)
的概念,幫助開發人員來解決這一問題。

密封類在宣告中使用sealed 修飾符,這樣就可以防止該類被其它類繼承。如果試圖將乙個密封類作為其它類的基類,c#就會提示出錯。

理所當然,密封類不能同時又是抽象類,因為抽象類總是希望被繼承的。

密封類可以阻止其它程式設計師在無意中繼承該類。而且密封類可以起到執行時優化的效果。實際上,密封類中不可能有派生類。如果密封類例項中存在虛成員函式,該成員函式可以轉化為非虛的,函式修飾符virtual不再生效。

為了明確宣告不允許建立某個類的例項,必須將那個類顯式地宣告為抽象類,抽象類試用於一些通用類。

這些類可能是某些派生類的基類,但使用時又不必要例項化。

抽象類可以包含抽象方法,抽象方法類似於virtual方法,但它不包含方法主體,必須(重點) 在派生類中重寫(override)方法。

例項**如下:

abstract class a

sealed class b: a

}

如果我們嘗試寫下面的**

class c: b
c#會指出這個錯誤,告訴你b是乙個密封類,不能試圖從b中派生任何類。

而除了密封類,c#還提出了密封方法這一概念

例項**如下:

using system ;

class a

public virtual void g( )

}class b: a

override public void g( )

}class c: b

}

類b對基類a中的兩個虛方法均進行了過載,其中f 方法使用了sealed 修飾符,成為乙個密封方法。g 方法不是密封方法,所以在b的派生類c中,可以過載方法g,但不能過載方法f。

ps:關於使用介面實現多級繼承的辦法我就直接貼**了,比較簡單,自行參悟

using system ;

//定義乙個描述點的介面

inte***ce ipoint

}//定義第二個描述點的介面

inte***ce ipoint2

}//在point中繼承了兩個父類介面,並分別使用了兩個父類介面的方法

class point:ipoint,ipoint2

//定義的屬性,ipoint介面方法實現

public int x

set}

//定義的屬性,ipoint2介面方法實現

public int y

set}

}

在c#中,多型性的定義是:同一操作作用於不同的類的例項,不同的類將進行不同的解釋,最後產生不同的執行結果。c#支援兩種型別的多型性:

● 編譯時的多型性

編譯時的多型性是通過過載來實現的。對於非虛的成員來說,系統在編譯時,根據傳遞的引數、返回的型別等資訊決定實現何種操作。

● 執行時的多型性

執行時的多型性就是指直到系統執行時,才根據實際情況決定實現何種操作。c#中,執行時的多型性通過虛成員實現。

編譯時的多型性為我們提供了執行速度快的特點,而執行時的多型性則帶來了高度靈活和抽象的特點。
多型性是類為方法(這些方法以相同的名稱呼叫)提供不同實現方式的能力。多型性允許對類的某個方法進行呼叫而無需考慮該方法所提供的特定實現。例如,每個類當中都寫有乙個draw函式,你就可以通過呼叫不同的類,去指定系統應該執行哪個類的draw函式。從而為函式的過載打下了基礎。

例項**如下:

using system ;

public class drawingbase

}public class line : drawingbase

}public class circle : drawingbase

}public class square : drawingbase

}public class drawdemo

}

輸出結果是:

i'm a line.

i'm a circle.

i'm a square.

i'm just a generic drawing object.

關於C 多型的思考

c 中,可以如下定義 base father new derived father 是基類引用,指向子類物件,這一點有點類似c 該引用的使用模式如下 先說結論 測試 如下 using logging class base public virtual void show2 public void m...

C 的繼承與多型

概念介紹 繼承 為了 的重用,保留基類的原本結構,並新增派生類的部分,同時可能覆蓋 overide 基類的某些成員。多型 一種將不同的特殊行為和單個泛化記號相關聯的能力,分為靜態多型和動態多型。繼承 乙個派生類可以通過繼承獲得基類的所有成員,而無需再次定義它們。分為public protected和...

C 的繼承與多型

概念介紹 繼承 為了 的重用,保留基類的原本結構,並新增派生類的部分,同時可能覆蓋 overide 基類的某些成員。多型 一種將不同的特殊行為和單個泛化記號相關聯的能力,分為靜態多型和動態多型。繼承 乙個派生類可以通過繼承獲得基類的所有成員,而無需再次定義它們。分為 public protected...