天天看点

构造函数的运用,体现类的自我维护

构造函数有很多用处,巧妙地运用构造函数能提高类的设计安全、合理和封装。

下面的类设计的不合理,要求用户在调用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

继续阅读