天天看點

構造函數的運用,展現類的自我維護

構造函數有很多用處,巧妙地運用構造函數能提高類的設計安全、合理和封裝。

下面的類設計的不合理,要求使用者在調用18行Pring方法前,先為17行指派。

1

構造函數的運用,展現類的自我維護

 public class Space

2

構造函數的運用,展現類的自我維護

 {

3

構造函數的運用,展現類的自我維護

4

構造函數的運用,展現類的自我維護

 public static void Main(string[] args)

5

構造函數的運用,展現類的自我維護

6

構造函數的運用,展現類的自我維護

7

構造函數的運用,展現類的自我維護

 FilePrint pring = new FilePrint();

8

構造函數的運用,展現類的自我維護

 //如果使用者忘記調用FileName,系統将不可靠

9

構造函數的運用,展現類的自我維護

 //pring.FileName = @"c:/text.txt";

10

構造函數的運用,展現類的自我維護

 pring.Print();

11

構造函數的運用,展現類的自我維護

 }

12

構造函數的運用,展現類的自我維護

13

構造函數的運用,展現類的自我維護

14

構造函數的運用,展現類的自我維護

 public class FilePrint

15

構造函數的運用,展現類的自我維護

16

構造函數的運用,展現類的自我維護

17

構造函數的運用,展現類的自我維護

 public string FileName = null;

18

構造函數的運用,展現類的自我維護

 public void Print()

19

構造函數的運用,展現類的自我維護

20

構造函數的運用,展現類的自我維護

 System.Console.WriteLine("Do prining {0}", FileName);

21

構造函數的運用,展現類的自我維護

22

構造函數的運用,展現類的自我維護

把代碼改為下面就合理的多

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 FilePrint pring = new FilePrint(@"c:/text.txt");

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 //代碼可以更簡約

構造函數的運用,展現類的自我維護

 new FilePrint(@"c:/text.txt").Print();

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public FilePrint(string path)

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 FileName = path;

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

23

構造函數的運用,展現類的自我維護

 public readonly string FileName = null;

24

構造函數的運用,展現類的自我維護

25

構造函數的運用,展現類的自我維護

26

構造函數的運用,展現類的自我維護

27

構造函數的運用,展現類的自我維護

28

構造函數的運用,展現類的自我維護

通過構造函數,強制使用者在執行個體化的時候給與FileName的值,調用更安全更簡約。

第23行對資料成員FileName修飾為readonly表示該資料成員為隻讀,隻讀的意思是,該成員隻有一次指派的機會(聲明時立即指派或在構造函數時指派)。readonly和const的差別是

readonly有兩種指派的機會:聲明時立即指派或在構造函數時指派

const隻有在聲明時指派

另外一個很值得注意的是,const其實就是static資料修飾,不過不能直接用static來修飾。const包括了static的含義,是以const需要通過類來通路。

我們再來看一個構造函數的運用

請仔細考慮一下代碼

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new SalesContract(100).SalePrice);

構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new SalesContract(100,120).SalePrice);

構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new SalesContract(100,120,180).SalePrice);

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public class SalesContract : Contract//銷售合同 

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public SalesContract(double costPrice)

構造函數的運用,展現類的自我維護

 : this(costPrice, costPrice)

構造函數的運用,展現類的自我維護

 { }

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public SalesContract(double costPrice, double minimumPrice)

構造函數的運用,展現類的自我維護

 : this(costPrice, minimumPrice, minimumPrice)

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public SalesContract(double costPrice, double minimumPrice, double salePrice)

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 CostPrice = costPrice;

構造函數的運用,展現類的自我維護

 MinimumPrice = minimumPrice;

29

構造函數的運用,展現類的自我維護

 SalePrice = salePrice;

30

構造函數的運用,展現類的自我維護

31

構造函數的運用,展現類的自我維護

32

構造函數的運用,展現類的自我維護

 private double MinimumPrice;//最低價

33

構造函數的運用,展現類的自我維護

 public double SalePrice;//銷售價格 

34

構造函數的運用,展現類的自我維護

35

構造函數的運用,展現類的自我維護

 public bool CheckPrice()//價格檢查

36

構造函數的運用,展現類的自我維護

37

構造函數的運用,展現類的自我維護

 return SalePrice < Math.Min(MinimumPrice, CostPrice);

38

構造函數的運用,展現類的自我維護

39

構造函數的運用,展現類的自我維護

 internal double PreferentialPrice;//優惠價

40

構造函數的運用,展現類的自我維護

41

構造函數的運用,展現類的自我維護

42

構造函數的運用,展現類的自我維護

 public class Contract//合同

43

構造函數的運用,展現類的自我維護

44

構造函數的運用,展現類的自我維護

45

構造函數的運用,展現類的自我維護

 public string Buyer;//買方

46

構造函數的運用,展現類的自我維護

 public string Seller;//賣方

47

構造函數的運用,展現類的自我維護

 protected double CostPrice;//成本價

48

構造函數的運用,展現類的自我維護

通過3個構造函數,使用者可以友善的對ConstPrice、SalePrice、MinimunPrice進行指派。

我們再來看一個關于構造函數的用例。

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new Order("123-12").OrderNumber);

構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new Order(Order.CreateOrderNumber()).OrderNumber);

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public class Order

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public Order(string orderNumber)

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 this.OrderNumber = orderNumber;

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 private static int Count;

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public readonly string OrderNumber;

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public static string CreateOrderNumber()

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 System.DateTime d = System.DateTime.Now;

構造函數的運用,展現類的自我維護

 return System.DateTime.Now.ToString("yMd-") + (++Count).ToString();

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

上面的代碼看似很合理,使用者可以自己定義OrderNumber也可以通過CreateOrderNumber方法,Order在構造時總是可以得到Number。

但這樣的設計,暴露了對CreateOrderNumber的調用。

我們看看經過修改後的設計

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 public Order():this(CreateOrderNumber())

構造函數的運用,展現類的自我維護

 { 

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 private static string CreateOrderNumber()

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

我們添加了一個預設的構造函數Order()在第9行,又把18行的CreateOrderNumber改為private,那麼這會有什麼效果呢?

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

 System.Console.WriteLine(new Order().OrderNumber);

構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護
構造函數的運用,展現類的自我維護

看到了嗎?在這個代碼中,如果使用者給與了Number則使用使用者給與的值,否則,Order能自動給與值。向使用者封裝了CreateOrderNumber的存在。這就是類設計的一個很重要的原則:自我維護。

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

繼續閱讀