天天看點

武俠世界中的:虛拟方法、重寫方法、抽象方法

虛拟方法virtual

被修飾為虛拟的方法,實作是可變的,派生類可以重寫基類的虛拟方法,也可以不重寫基類的虛拟方法

1

武俠世界中的:虛拟方法、重寫方法、抽象方法

public class Space

2

武俠世界中的:虛拟方法、重寫方法、抽象方法

 {

3

武俠世界中的:虛拟方法、重寫方法、抽象方法

4

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public static void Main(string[] args)

5

武俠世界中的:虛拟方法、重寫方法、抽象方法

6

武俠世界中的:虛拟方法、重寫方法、抽象方法

7

武俠世界中的:虛拟方法、重寫方法、抽象方法

 new Order().Submit();//to default department

8

武俠世界中的:虛拟方法、重寫方法、抽象方法

 new ShipOrder().Submit();//to default Ship department

9

武俠世界中的:虛拟方法、重寫方法、抽象方法

 new InOrder().Submit();//to default department

10

武俠世界中的:虛拟方法、重寫方法、抽象方法

 new OutOrder().Submit();//to default Out department /n to default department

11

武俠世界中的:虛拟方法、重寫方法、抽象方法

 }

12

武俠世界中的:虛拟方法、重寫方法、抽象方法

13

武俠世界中的:虛拟方法、重寫方法、抽象方法

14

武俠世界中的:虛拟方法、重寫方法、抽象方法

15

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Order

16

武俠世界中的:虛拟方法、重寫方法、抽象方法

17

武俠世界中的:虛拟方法、重寫方法、抽象方法

18

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public virtual void Submit()

19

武俠世界中的:虛拟方法、重寫方法、抽象方法

20

武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("to default department");

21

武俠世界中的:虛拟方法、重寫方法、抽象方法

22

武俠世界中的:虛拟方法、重寫方法、抽象方法

23

武俠世界中的:虛拟方法、重寫方法、抽象方法

24

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class ShipOrder : Order

25

武俠世界中的:虛拟方法、重寫方法、抽象方法

26

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void Submit()

27

武俠世界中的:虛拟方法、重寫方法、抽象方法

28

武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("to default Ship department");

29

武俠世界中的:虛拟方法、重寫方法、抽象方法

30

武俠世界中的:虛拟方法、重寫方法、抽象方法

31

武俠世界中的:虛拟方法、重寫方法、抽象方法

32

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class InOrder : Order

33

武俠世界中的:虛拟方法、重寫方法、抽象方法

 { 

34

武俠世界中的:虛拟方法、重寫方法、抽象方法

35

武俠世界中的:虛拟方法、重寫方法、抽象方法

36

武俠世界中的:虛拟方法、重寫方法、抽象方法

37

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class OutOrder : Order

38

武俠世界中的:虛拟方法、重寫方法、抽象方法

39

武俠世界中的:虛拟方法、重寫方法、抽象方法

40

武俠世界中的:虛拟方法、重寫方法、抽象方法

41

武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("to default Out department");

42

武俠世界中的:虛拟方法、重寫方法、抽象方法

 base.Submit();

43

武俠世界中的:虛拟方法、重寫方法、抽象方法

44

武俠世界中的:虛拟方法、重寫方法、抽象方法

在以上代碼中,基類Order的Submit方法被修飾為virtual的,是以ShipOrder 和OutOrder 可以重新定義Submit的具體實作(用override 關鍵

字),并且還可以使用關鍵字base來調用基類的方法。

在講到方法重寫的時候,就必須要了解對象的資料類型轉換。

在資料類型中,我們知道 資料容量小的(比如int)可以被安全的轉換到資料容量大的(比如long)類型,反之是不安全的。

在對象世界正好相反,資料容量大的(子類)可以被安全的轉換到資料容量小的(子類的基類)類型,反之是不安全的。

是以,所有的資料類型,都可以被安全的轉為object,就是這個道理。

以下代碼示範了對象的資料類型轉換

武俠世界中的:虛拟方法、重寫方法、抽象方法

 Order order = new ShipOrder();//可以,子類轉為基類

武俠世界中的:虛拟方法、重寫方法、抽象方法

 order.Submit();//to default Ship department

武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("type is {0}", order.GetType());//type is ShipOrder

武俠世界中的:虛拟方法、重寫方法、抽象方法

 ShipOrder ship = (ShipOrder)order;//可以,order是從ShipOrder轉來的,但由于是基類轉子類,必須強制類型轉換

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("type is {0}", ship.GetType());//type is ShipOrder

武俠世界中的:虛拟方法、重寫方法、抽象方法

 order = new Order();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 ship = (ShipOrder)order;//不可以,order中沒有ShipOrder的成員,編譯正确,運作錯誤

武俠世界中的:虛拟方法、重寫方法、抽象方法

 InOrder inorder = new InOrder();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 ship = (ShipOrder)inorder;//不可以,編譯錯誤

在金庸小說《倚天屠龍記》中描述了virtual方法的含義

隻聽張三豐問道:“孩兒,你看清楚了沒有?”張無忌道:“看清楚了。”張三豐道:“都記得了沒有?”張無忌道:“已忘記了一小半。”

張三豐道:“好,那也難為了你。你自己去想想罷。”張無忌低頭默想。過了一會,張三豐問道:“現下怎樣了?”張無忌道:“已忘記了一

大半。”張三豐畫劍成圈,問道:“孩兒,怎樣啦?”張無忌道:“還有三招沒忘記。”張三豐點點頭,放劍歸座。張無忌在殿上緩緩踱了一

個圈子,沉思半晌,又緩緩踱了半個圈子,擡起頭來,滿臉喜色,叫道:“這我可全忘了,忘得乾乾淨淨的了。”張三豐道:“不壞,不壞!

忘得真快”

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Shadowboxing

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public virtual void 白鶴亮翅()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public virtual void 如封似閉()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public virtual void 野馬分鬃()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Zhang : Shadowboxing//張無忌繼承張三豐的拳法

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 白鶴亮翅()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 如封似閉()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

我們再來看抽象方法abstract

抽象的方法隐含的為虛拟的方法,抽象的方法要求派生類必須重寫,抽象的方法沒有方法體。

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract class Order

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void Submit();

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract class InOrder : Order

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

Order定義了抽象的Submit,是以隻能定義傳回值,方法名稱,參數清單和通路修飾。有抽象方法的類一定是抽象類(抽象類不一定需要抽象方法)

子類可以實作抽象方法,比如ShipOrder和OutOrder 

子類也可以不實作抽象方法,比如InOrder

金庸同志也同時描述了一個關于abstract的例子,威震天下的獨孤九劍就是典型的抽象類型

獨孤大俠是絕頂聰明之人,學他的劍法,要旨是在一個‘悟’字,決不在死記硬記。等到通曉了這九劍的劍意,則無所施而不可,便是将全部

變化盡數忘記,也不相幹,臨敵之際,更是忘記得越幹淨徹底,越不受原來劍法的拘束。

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract class AloneSwordsmanship//獨孤九劍

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破劍式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破刀式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破槍式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破鞭式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破索式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破掌式();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract void 破氣式();

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Feng : AloneSwordsmanship//風清揚繼承獨孤九劍

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破劍式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破刀式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破槍式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破鞭式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破索式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破掌式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public override void 破氣式()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

45

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Chong : Feng//令狐沖繼承風清揚

46

武俠世界中的:虛拟方法、重寫方法、抽象方法

47

武俠世界中的:虛拟方法、重寫方法、抽象方法

48

武俠世界中的:虛拟方法、重寫方法、抽象方法

重寫方法override

隻可以重寫基類為虛拟或抽象的方法

必須有相同的簽名、不可以更改通路修飾、不可以更改傳回值、不可以更改參數清單、不可以更改方法名稱、被重寫後的方法一定可以再重寫

不能是靜态方法static、不能是密封方法

是以嚴格的來講,令狐沖從風清揚那裡得到的是已經重寫後的類,不是抽象方法了,風清揚從獨孤九劍那裡擷取的才是真正的抽象劍法。

當基類中沒有定義為虛拟或者抽象的方法時

一般的方法是不允許被override的。不過有時候子類一定要有自己的特色,那怎麼辦呢?new一個方法。

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public void Send()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("Sendto Out department");

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class Delivery : OutOrder

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public new void Send()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 System.Console.WriteLine("Sendto Delivery department");

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

注意OutOrder 定義的Send方法沒有可以重寫的修飾,但子類Delivery 通過new void Send覆寫了基類的方法,是以請注意下面的調用代碼

武俠世界中的:虛拟方法、重寫方法、抽象方法

 OutOrder outorder = new OutOrder();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 outorder.Send();//Sendto Out department

武俠世界中的:虛拟方法、重寫方法、抽象方法

 Delivery delivery = new Delivery();

武俠世界中的:虛拟方法、重寫方法、抽象方法

 delivery.Send();//Sendto Delivery department

武俠世界中的:虛拟方法、重寫方法、抽象方法

 outorder = delivery;

武俠世界中的:虛拟方法、重寫方法、抽象方法

 outorder.Send();//注意:Sendto Out department

當子類用new覆寫了基類的方法時,若引用變量為子類,則運作的是子類的new方法;若引用變量是基類,則運作基類方法。

剛才說到了抽象方法和抽象類,我們要再次提醒,有抽象方法的一定是抽象類,但是抽象類不一定包含抽象方法。

嫁衣神功就是典型的沒有抽象方法的抽象類,嫁衣神功的修練者本身不能享用嫁衣神功的威力(類不能執行個體化),要把功力傳給他人(必須有子類繼承)

以下是一個沒有抽象方法的抽象類的例子:

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public abstract class Contract//合同

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

/* public Contract()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 BillCount++;

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 */ 

武俠世界中的:虛拟方法、重寫方法、抽象方法

 //抽象類沒有必要寫構造函數

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public string Buyer;//買方

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public string Seller;//賣方

武俠世界中的:虛拟方法、重寫方法、抽象方法

 protected double CostPrice;//成本價

武俠世界中的:虛拟方法、重寫方法、抽象方法

 public double SalePrice;//銷售價格 

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public bool CheckPrice()

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 return SalePrice > CostPrice;

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 public class SaleContract : Contract

武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法
武俠世界中的:虛拟方法、重寫方法、抽象方法

 } 

武俠世界中的:虛拟方法、重寫方法、抽象方法

本文轉自shyleoking 51CTO部落格,原文連結:http://blog.51cto.com/shyleoking/806279

繼續閱讀