那接下来我们肯定要做一些不同的查询、修改等,例如新闻栏目和用户管理这两个相同的是都需要使用到前面我们说的类,但是不同的是他们所要结果又各不相同。怎么办?有两种办法,一是为他们分别创建类,把数据库连接类的东西复制两次,这样做的缺点我想不用多说了吧,那么我们还可以频繁的调用数据库类的成员来达到目的,可这样下来,我们的代码岂不是很臃肿了?知道减肥药为什么那么好卖吗?
郁闷,那怎么办呢?简单,我们用继承来完成,简单形容下继承吧,他呢就是 子类(派生类)拥有 父类(基类)的全部特性,同时又有自己的特色。我想这样说应该还是算明白了吧!
注意:.Net的继承只允许直接从另一个类中继承,不能同时继承多个类,好像说只能有一个老爹(其实这也不绝对,哈哈想下微软真的很有意思,我们还可以使用接口实现多重继承),但是可以多层次的继承,例如可以上有老爹,还有爷爷,下有儿子,孙子。
下面我们看个直观点的东西
我们看上图就会发现,越下层的越具体.那么我们就可以理解为人是所有类的基类(父类),而下面的则都为派生类(子类).事实上我们下面的子类又可以向下延伸.
C#中,派生类从它的直接基类中继承成员:方法、域、属性、事件、索引指示器。除了构造函数和析构函数,派生类隐式地继承了直接基类的所有成员。
二、C#中的继承符合下列规则:
(这个不是我总结的,我去网上粘人家写现成的.呵呵!!)
1、继承是可传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。Object 类作为所有类的基类。
2、派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。
3、构造函数和析构函数不能被继承。除此以外的其它成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。
4、派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不因为这派生类删除了这些成员,只是不能再访问这些成员。(这点需要注意的是,如果是属性或者方法同名,但是签名不同,那就不是覆写,而是重载了)
5、类可以定义虚方法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性。
6、派生类只能从一个类中继承,可以通过接口实现多重继承。
在子类中我们可以通过base 关键字访问基类的成员:
调用基类上已被其他方法重写的方法。
指定创建派生类实例时应调用的基类构造函数。
基类访问只能在构造函数、实例方法或实例属性访问器中进行。
从静态方法中使用 base 关键字是错误的。
再重温下 访问修饰符
访问修饰符是一些关键字,用于指定声明的成员或类型的可访问性。类的继承中有四个访问修饰符: public protected internal private。使用这些访问修饰符可指定下列五个可访问性级别: public protected internal internal protected private。
声明的可访问性 | 意义 |
public | 访问不受限制。 |
protected | 访问仅限于包含类或从包含类派生的类型。 |
internal | 访问仅限于当前项目。 |
protected internal | 访问仅限于从包含类派生的当前项目或类型。 |
private | 访问仅限于包含类型。 |
Code:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partial class lei_jicheng : System.Web.UI.Page
13{
14 //sealed class ren //使用sealed将实现对类的密封,结果就是这个类无法被继承.密封类不能同时又是抽象类,因为抽象类总是希望被继承的。
15 public class ren
16 {
17 protected int yan; //定义人的眼睛数量,别说俺废话哈
18 protected int shou; //定义手
19
20 //定义一个事件
21 public delegate void RenChengHender(string s,int e); //定义一个委托
22 public event RenChengHender RenChenged; //定义一个事件
23
24 //构造函数
25 public ren()
26 {
27 yan = 1;
28 shou = 2;
29
30 }
31 public ren(int y,int s)
32 {
33 yan = y;
34 shou = s;
35 }
36 //属性
37 public int Yan
38 {
39 get
40 { return yan; }
41 set
42 {
43 yan = value;
44 string s = "yan";
45 RenChenged(s,value);//如果修改了这个值,将激发事件
46 }
47 }
48 public int Shou
49 {
50 get
51 { return shou; }
52 set
53 {
54 shou = value;
55 string s = "shou";
56 RenChenged(s, value);
57 }
58 }
59 //方法
60 public string yanjin(int y)
61 {
62 switch (y)
63 {
64 case 0:
65 return "做人要厚道,再怎么也该给人一只眼睛撒";
66 break;
67 case 1:
68 return "他还有只眼睛呢??????";
69 break;
70 case 2:
71 return "普通人嘛,没意思";
72 break;
73 case 3:
74 return "难道二郎神有儿子了?";
75 break;
76 default:
77 return "别玩啦,会死人的";
78 break;
79 }
80 }
81 }
82 public class man : ren //创建一个继承类
83 {
84 private int age;
85 private string sex;
86
87 public man(int a,string s,int y):base(6,888)//实际上,我们在这里使用 : 和 base 完成了子类在初始化时与父类的通信
88 {
89 age = a;
90 sex = s;
91 yan = y;
92 }
93 public string ManRen
94 {
95 get
96 {
97 return "一个" + sex + "人,他有" + yan + "只眼睛和" + shou + "只手,他今年已经" + age + "岁了";
98 }
99 }
100 public string suibian()
101 {
102 return base.Shou.ToString()+","+this.Yan.ToString(); //通过base或者this,访问基类成员
103 }
104 public string yanjin(string a,int s)//这里我们为子类编写了一个简单的方法,他与基类中方法是同名的,但是签名不同.所以会被重载
105 {
106 return a + "和" + s;
107 }
108
109 //这个方法同基类中的方法名和签名都完全一样
110 //因为这样做就隐藏了基类的同名方法,假设我们是有意隐藏的,所以使用了new关键字显式隐藏从基类继承的同名方法
111 public new string yanjin(int y)
112 {
113 string bl=base.yanjin(y);//这里我们使用base调用基类的同名方法
114 return "父类方法被覆写,现在返回的是" + y+"我们调用基类同名方法所得结果为:"+bl;
115 }
116 }
117 protected void Page_Load(object sender, EventArgs e)
118 {
119 ren aa = new ren(2, 2);//创建一个ren类的对象
120 aa.RenChenged += new ren.RenChengHender(aa_RenChenged); //注册一个事件,一旦下面发生则会发生下面的事件
121
122 aa.Yan = 3;//赋值,触发事件,结果当为"我还不信,那个有三只眼睛?"
123 aa.Shou = 2;//触发事件,结果为 "一切正常哈,只有两只手"
124
125 Response.Write("<p>眼睛有" + aa.Yan + "只,,手有" + aa.Shou);//打印出来,结果为 "眼睛有3只,,手有2"
126
127 Response.Write("<p>方法返回的是:" + aa.yanjin(3)); //调用事件,显示为 "方法返回的是:难道二郎神有儿子了?"
128
129
130 man mrr = new man(23, "男",4);
131 Response.Write("<p>" + mrr.ManRen); //显示结果为 "一个男人,他有4只眼睛和888只手,他今年已经23岁了"
132 Response.Write("<p>子类对象调用父类方法返回的是:" + mrr.yanjin(0));
133 //上面这句结果为"子类对象调用父类方法返回的是:父类方法被覆写,现在返回的是0我们调用基类同名方法所得结果为:做人要厚道,再怎么也该给人一只眼睛撒
134
135 Response.Write("<p>子类对象调用父类方法返回的是:" + mrr.yanjin("aa", 5));//返回结果为 "子类对象调用父类方法返回的是:aa和5"
136 Response.Write("<p>" + mrr.suibian()); //返回结果为 "888,4"
137
138 }
139
140 void aa_RenChenged(string s,int e)//下面是我们给修改眼睛和手做的一个事件
141 {
142 if (s == "yan")
143 {
144 if (e == 3)
145 {
146 Response.Write("我还不信,那个有三只眼睛?");
147 }
148 }
149 if (s == "shou")
150 {
151 if (e == 2)
152 {
153 Response.Write("<p>一切正常哈,只有两只手");
154 }
155 }
156 }
157}
158