继承是OOP的一个方面,好处在于促进代码重用。代码重用分为两类:经典继承--“is-a”以及包含/委托模型--“has-a”。
首先“is-a”,在两个或两个以上的类类型之间构造依赖关系,新的类可以利用既有类的功能。
以下是一个“is-a”的例子:
1 class Car
2 {
3 protected readonly int maxSpeed;
4 private int currSpeed;
5 private int cost;
6 private DateTime dateInProduced;
7 private string model;
8
9 protected Car(int max, int cos, DateTime date, string mod)
10 {
11 currSpeed = max;
12 cost = cos;
13 dateInProduced = date;
14 model = mod;
15 }
16
17 protected Car()
18 {
19 currSpeed = 55;
20 }
21
22
23
24 public DateTime Date
25 {
26 get { return dateInProduced; }
27 set { dateInProduced = value; }
28 }
29
30 public int Speed
31 {
32 get { return currSpeed; }
33 set
34 {
35 currSpeed = value;
36 if (currSpeed > maxSpeed)
37 {
38 currSpeed = maxSpeed;
39 }
40 }
41 }
42
43 public int Cost
44 {
45 get { return cost; }
46 set { cost = value; }
47 }
48 private int price;
49
50 public int Price
51 {
52 get { return price; }
53 set { price = value; }
54 }
55
56 public string Model
57 {
58 get { return model; }
59 set { model = value; }
60 }
61 }
62
63 class MiniVan : Car
64 {
65 public MiniVan(int speed, int cost, DateTime date, string mod,int sale)
66 : base(speed, cost, date, mod)
67 {
68 SaleNumber = sale;
69 }
70
71
72 public int SaleNumber
73 {
74 get;
75 set;
76 }
77 }
78
79 static void Main(string[] args)
80 {
81 MiniVan myVan = new MiniVan(10,100,DateTime.Now,"Mini",10000);
82 myVan.Speed = 10;
83 Console.WriteLine("My van is {0}|{1}|{2}|{3}|{4}", myVan.Speed, myVan.Cost, myVan.Date, myVan.Model, myVan.SaleNumber);
84 Console.ReadLine();
85 }
注意几个问题, 第一:父类中的私有成员,派生类是绝不能访问;
第二:C#要求一个类只能有一个直接基类;
第三:被“sealed”关键字修饰的类将不能被继承;
第四:被“protected”修饰的成员或者数据可以直接被派生类访问,属于“可以在家族里分享的秘密”。
第五:善用“base”关键字,显示调用合适的自定义基类构造函数而不是使用默认构造函数。
针对上一段中第四点要补充一下,可以把一个类里面的属性理解为套在数据或成员外面的一层壳,也就是说凡是属性,它必然就是“public”。父类中的属性如果是“protected”,那么其派生类依然不能访问这个属性。如以下代码:
class Car
{
protected readonly int maxSpeed;
private int currSpeed;
protected Car(int max)
{
currSpeed = max;
}
protected Car()
{
currSpeed = 55;
}
/// <summary>
/// 此时会编译错误!!!!!
/// </summary>
protected int Speed
{
get { return currSpeed; }
set
{
currSpeed = value;
if (currSpeed > maxSpeed)
{
currSpeed = maxSpeed;
}
}
}
针对上一段中第五点要说明一下,在C#下,一般基类的默认构造函数会在派生类构造函数执行之前被自动调用,所以用“base”关键字可以显示调用基类特定构造函数而不是默认构造函数,这样可以减少对基类的访问。
下面是一个“has-a”的例子:
1 class Car
2 {
3 private int currSpeed;
4 private int cost;
5 private DateTime dateInProduced;
6 private string model;
7
8 public Car(int max, int cos, DateTime date, string mod)
9 {
10 currSpeed = max;
11 cost = cos;
12 dateInProduced = date;
13 model = mod;
14 }
15
16 public Car()
17 {
18 currSpeed = 55;
19 }
20
21 /// <summary>
22 /// 每辆车子都会有保险
23 /// </summary>
24 public class BenefitPackage
25 {
26 /// <summary>
27 /// 保险会有不同的档次,这里用一个枚举类
28 /// </summary>
29 public enum BenefitPackageLevel
30 {
31 Standard,Gold,Platinum
32 }
33
34 /// <summary>
35 /// 根据不同档次获取保险费
36 /// </summary>
37 /// <param name="Level"></param>
38 /// <returns></returns>
39 public double ComputePayDeduction(BenefitPackageLevel Level)
40 {
41 switch (Level)
42 {
43 case BenefitPackageLevel.Standard:
44 return 100.00;
45 case BenefitPackageLevel.Gold:
46 return 150.00;
47 case BenefitPackageLevel.Platinum:
48 return 200.00;
49 default :
50 return 0;
51 }
52 }
53 }
54
55
56 public DateTime Date
57 {
58 get { return dateInProduced; }
59 set { dateInProduced = value; }
60 }
61
62 public int Cost
63 {
64 get { return cost; }
65 set { cost = value; }
66 }
67 private int price;
68
69 public int Price
70 {
71 get { return price; }
72 set { price = value; }
73 }
74
75 public string Model
76 {
77 get { return model; }
78 set { model = value; }
79 }
80 }
81
82 static void Main(string[] args)
83 {
84 Car.BenefitPackage.BenefitPackageLevel BenefitLevel = Car.BenefitPackage.BenefitPackageLevel.Platinum;
85 Car.BenefitPackage myBenefit=new Car.BenefitPackage();
86 double money=myBenefit.ComputePayDeduction(BenefitLevel);
87 Console.WriteLine(money.ToString());
88 Console.ReadLine();
89 }
所谓“has-a”其实就是类与类之间产生嵌套关系,每个车子都会有它自己的保险类型和保险金数额,但BenefitPackage与Car肯定不可能是“is-a”的关系,这是“has-a”就显得非常合适了。
尽管语法很简洁,例子也很简单,但嵌套类这项技术是很有思考余地的:
1)通过嵌套类可以完全控制内部类型的访问级别,也就是可以声明为私有(非嵌套类不能私有)。
2)由于嵌套类是包含类的成员,所以它可以访问包含类的私有成员。
3)嵌套类型只是用于包含类的辅助方法,不是为外部世界所准备的。
用两个简单的例子把自己理解的继承说明一下,.Net很多技术都是完全基于面向对象思想产生的,理解这些技术要用面向对象的思想,也通过理解这些技术更好的领悟面向对象的思想,总之将面向对象进行到底。
本人也不是大牛,只是本着加深印象和交流为目的写博客。欢迎高手、大牛多多指正,本人不胜感激。
感恩ing,谦卑ing。