第六章 初始继承和多态
C# 继承
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。
1 什么是继承
继承是使用已经存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用已存在的类的功能。
继承是面向对象编程中的一个非常重要的特性。在有继承关系的二个类中,子类不仅具有自己独立有的成员,还具有父类的成员
继承关系在类图中表示一个箭头,箭头指向的是父类
base关键字和protected修饰符
都知道this表示当前实例,通过他可以访问类本身的成员,C#中还有一个关键字base,他表示父类,可以用于访问父类的成员。
在子类中可以用base调用父类的属性。实际上,还可以用base关键字调用父类的方法及父类的构造函数
父类中的成员如果用private修饰,他将作为私有成员,其他任何类都无法访问。如果设置为public成员,任何类都可以访问该成员。
在C#中提供了另一种访问修饰符protected,被这个访问修饰符修饰的成员允许被其子类访问,而不允许其他非子类访问
举例说明:
public class A
{
public A(){}
}
public class B:A
{
public B(){}
}
public ,private ,protected的区别
修饰符 类内部 子类 其他类
public 可以 可以 可以
protected 可以 可以 不可以
public 可以 不可以 不可以
可以看出,三种访问修饰符对类成员的访问限制强度:private>protected>public
子类构造函数
隐式调用父类构造函数
is a 的应用
继承的价值
体会一下继承的特点
继承模拟了现实世界的关系,oop中强调一切皆对象,这符合我们面向对象编程的思考方向
继承实现了代码的重用,合理的使用继承,会使代码更加简洁
继承使程序结构清晰,子类和父类的层次结构清晰,最终的目的是使子类只关注子类的相关行为和状态,无须关注父类的行为与状态
解决继承带来的问题
public virtual string SayHi(){
//方法体
}
像这种使用virtual 关键字修饰的方法,称为虚方法。虚方法有方法体
语法
访问修饰符 virtual 返回类 方法名(){
//方法体
}
public override string SayHi(){
//方法体
}
像这种通过override关键字来修饰的方法,称为方法的重写。虚方法可以被重写
语法
访问修饰符 override
返回类 方法名(){
//方法体
}
什么是多态
实现多态
实现方法的重写
父类中定义SayHi()方法,用virtual关键字定义为虚方法
在子类中定义子类自己的SayHi(),用override关键字修饰,就实现了对父类SayHi()方法的重写
定义父类变量,用子类对象初始化父类变量
多态按字面的意思就是 多种形态,指同一个作用于不同的对象时,可以有不同的解释,产生不同的执行结果
可以用虚方法实现多态
base关键字和protected修饰符
我们知道this关键字可以表示当前类的实例,通过它可以访问类本身的成员,在C#中还有一个base关键字表示父类,它可以用于访问父类的成员。
如在SE类中可以通过base.Age访问Empployee类的Age属性。
父类中的成员如果用private修饰,它将作为私有成员,其他任何类都无法访问。如果设为public则任何类都可以访问,C#中还提供了另一种修饰符,被这个修饰符修饰的成员允许被其子类访问而不允许被其他非子类访问。
三种修饰符对类成员的限制强度如下:
private>protected>public
子类构造函数
隐式调用父类构造函数
在创建子类的实例对象是会先调用父类的构造函数,如果我们不显示的指定调用父类构造函数系统会自动隐式的调用父类的无参构造,如果父类没有无参构造则必须显示的指定调用要调用的父类构造。
显示调用父类的构造函数
上面说到使用base关键字可以表示父类所以只要在子类的构造函数后添加:base(参数列表)就可以指定该构造函数调用父类的那个构造了如下所示:
public SE(int age,string gender,string id,string name,List<job> worklist,int _popularity):base(age,gender,id,name,worklist) { this._popularity = _popularity; }
继承的使用
继承的传递性:
继承的传递性指:子类具有父类的特征,如果父类是其他类的子类则该类也具有父类的父类的特征。
比如说卡车和公共汽车都具有汽车的特征,他们都是汽车类的子类,而且卡车还可以分为小型卡车和大型卡车他们都具有卡车的特征是卡车的子类同时他们还都具有汽车的特征,公共汽车可以分为单层和双层他们都具有公共汽车的特征,是公共汽车的子类,同时他们也都具有汽车的特征。
继承的单根性:
继承的单根性指:一个类不能同时继承多个类。
is关键字
is关键字用于判断对象是否属于给定的类型。比如我们创建一个SE类对象(se),可以使用is关键字判断他是否属于Empployee类
if(se is Empployee) { //属于 }else { //不属于 }
继承的价值
继承模拟了现实世界的关系,OOP中强调一切皆对象,这符合我们面向对象编程的思考方向。
继承实现的代码重用,合理的使用继承会是代码更加简洁。
继承使得程序结构清晰,子类和父类的层次结构清晰,最终的目的是的子类只关注子类的相关行为个状态而无需关注父类的行为和状态。
多态
virtual关键字
使用virtual关键字修饰的方法,称为虚方法,虚方法有方法体。语法如下:
访问修饰符 Virtual 返回值类型 方法名() { //方法体 }
override关键字
使用override关键字修饰的方法,称为方法的重写。虚方法可以重写。方法重写语法如下:
访问修饰符 override 返回值类型 方法名() { //方法体 }
注意:
父类中的的虚方法并非必须由子类重写,可以在父类中定义虚方法的默认实现,如果子类不对该方法重写则依然执行父类的默认实现。如果对方法进行重写则执行子类重写后的方法。
什么是多态?
多态的意思就是指同一操作作用于不同的对象时可以有不同的解释,产生不同的执行效果!
实现多态
实现方法重写
父类中定义SayHi()方法,用virtual关键字定义虚方法。
在子类总定义子类自己的SayHi()方法,用override关键字修饰,就实现了对父类SayHi()方法的重写。
定义父类变量,用子类对象初始化父类变量,
Employee ema =new SE(“210”,“Ema”,33,Gender.female,100);
直接用这个父类变量就可以掉用子类的SayHi()方法,系统可以根据对象运行时的类型决定调用那个方法,从而实现类的多态性。
子类构造:
1.找到子类构造
2.不进入子类构造体,跳转到父类构造
3.执行父类构造体,并且创建出父类对象
4.进入子类构造体,并执行
5.返回到Main,创建出子类对象