不跟你扯这没用的,我们来看个最简单的实例。透视图如图4-25
图4-25
从继承的透视图中可以看到,Child类继承了Parent类,在声明了Child 对象的后,对其实例化的时候,我们将可以看到,我们可以对父类的属性X进行赋值,即如果Class Child是继承Class Parent而来,那么Child的对象中包含一个Parent的对象的属性和方法。
例:采用继承的方法来计算长方形面积,设计如下图4-26:
图4-26
类Parent和类Child的代码如下:
//---------------------类Parent------------------------ public class Parent { public int x { get; set; } } //---------------------类Chile------------------------ public class Child : Parent { public int y { get; set; } public bool mianji() { //注意base表示访问基类的非私有(private)成员,this表示访问本类的成员 //通常可以不写,但当基类成员和当前类成员名字有冲突的时候就很有用了 base.x *= this.y; return true; } } |
“计算”按钮的事件代码如下
private void button1_Click(object sender, EventArgs e) { Child ch = new Child(); ch.x = int.Parse(this.number1.Text); ch.y = int.Parse(this.number2.Text); ch.mianji(); this.lbl_Area.Text = ch.x.ToString(); } |
小天:类只能继承一个吗?有什么办法使一个派生类继承多个基类?
老田:C#中式不允许对类进行多重继承的,如果一定要多重继承,只能多继承几层。比如A下面派生出B,B下面再派生出C这种形式。下面我们使用了一个汽车的实例,类关系图如图4-27
图4-27
在上图中,可以看到一共有4个类,最顶端的基类是Car(车),在Car下面分别继承了Truck(卡车)和Passenger(客车),在客车下面又派生了一个Saloon(轿车)类。属性和方法都在上面的类关系图中看得见了,你自己尝试下将代码写出来吧。写完了对比下我下面写的代码
/// <summary> /// ---------------汽车类,所有类的基类------------------ /// </summary> public class Car { private int dang; private int chemen; private string cheming; /// <summary> /// 构造函数 /// </summary> /// <param name="d">自动挡1,手动挡2</param> /// <param name="c">车门数量</param> /// <param name="cm">车名或型号</param> public Car(int d,int c,string cm) { dang = d; chemen = c; cheming = cm; } public int Dang {// 自动挡1,手动挡2 get { return dang; } set { dang = value; } }
public int Chemen {// 车门数量 get { return chemen; } set { chemen = value; } }
public string Cheming {// 车名或型号 get { return cheming; } set { cheming = value; } } /// <summary> /// 启动 英语差的命名方法 - 拼音 /// </summary> public void qidong() { //方法体 }
/// <summary> /// 停车 ,此方法只对子类开放,不对外 /// 在常规项目中,非特别情况一般要么私有,要有公开 /// </summary> protected void tingche() { //方法体 }
/// <summary> /// 自动刹车,此方法不对外,自己用来吓开车的人用 /// </summary> private void zidongshache() { //方法体 } } /// <summary> /// -----------------------客车类------------------------- /// </summary> public class Passenger : Car //该类继承了Car类 { public Passenger() : base(1, 5, "OUYE") { //派生类中的构造函数, //: base(1, 5, "OUYE"),这一句用来实例化基类的构造函数 //为什么要实例化基类的构造函数呢? //因为即使实例化本类的对象,我们也会大量的使用基类的类成员 //为什么上一个计算面积的没有这样做呢? //因为那个父类没有构造函数,不需要初始化基类中的成员 } /// <summary> /// 座位数量 /// </summary> public string Zuowei { get; set; } /// <summary> /// 启动 英语差的命名方法 - 拼音 /// </summary> public void qidong() { //方法体 } }
/// <summary> /// ------------------------轿车类-------------------------- /// </summary> public class Saloon : Passenger //该类继承了Passenger类 { /// <summary> /// 轿车类型,比如跑车、破车(O(∩_∩)O)、家用车、商用车 /// </summary> public string Chexing { get; set; } } /// <summary> /// ------------------------卡车类--------------------------- /// </summary> public class Truck : Car //该类也继承了Car类 { public Truck() : base(2, 2, "YEYE") { //注释参考Passenger类构造函数 } /// <summary> /// 载重 /// </summary> public float Zaizhong { get; set; } } |
小天:继承之后如何使用,用的时候是实例化基类还是实例化子类?
老田:我昏,肯定实例化子类嘛,都说了,子类继承了父类之后,也同时拥有了父类中那些非私有的类成员。如图4-28
图4-28
小天:很奇怪,Car类中那个zidongshache(自动刹车)的方法和tingche()怎么没有继承过来?
老田:zidongshache这个方法的修饰符是不是private?而被private修饰过的类成员是否是就私有了?其实这个道理很简单。父类并非所有的东西都需要被子类继承的,比如曹操死之后,他所有的钱、权都被继承给了他的儿子。可是他所获得的名誉,他的后宫却不能继承下去,就是这个道理。
而tingche这个方法的访问修饰符是protected,在封装那一节中讲到,被protected封装的类成员只被继承类完全可见,但是好像没有说在外面也完全可见哦。
小天:明白了,原来是因为访问修饰符决定了基类成员对外甚至自己的派生类的可见。我有如下三个问题:
- 第一,有什么办法可以让派生类去访问基类的成员呢?
- 第二,有什么办法让类无法被继承?
- 第三,你看,在Car类中的启动方法,但是这个方法是对于所有汽车来说的,可是不同的车,具体要启动内部所执行的方法肯定有所不同。但是父类中都已经写死了,还有什么办法可以改变没有?
本文章为天轰穿原创文章,转载请注明出处及作者。