1.继承
概念:因为我们在设计不同类的时候,会发现有些类中会出现大量的重复的代码(属性、方法),为了减少冗余代码,我们把这些重复内容,单独的抽取出来封装在一个类中。
让其他类从这个类中提取【相同】的成员。
这个类我们称之为父类也叫基类,其他类称之为子类,也叫【派生类】。
继承语法::【英文半角】父类的名字
继承优点:
1、减少了大量的冗余代码
2、让类与类产生了联系,为我们后期学习多态,打下了基础。
继承细节:
1、重名问题
如果子类的成员名称跟父类的成员名称一毛一样,那么子类对隐藏掉父类的成员,
隐藏的结果,子类调用不到父类的同名成员,只能调用自己的。
例如图所示:一毛一样子类会覆盖父类调用不到父类方法。
如果是故意这样使用的,可以使用关键字new来去掉警戒线。
new:
a、创建对象
b、隐藏父类成员
2、重名之后,如果我子类,就要调父类的方法,怎么办?
类的外部,是无论如何都调用不到的。
类的内部,可以通过base调用父类的成员.base表示的是父类对象
3、子类继承了父类,子类继承了父类的哪些成员?
属性和方法,子类有没有继承子类的私有字段?子类没有继承父类的私有字段。
子类内部,尽可能的使用this关键字调用自己的成员以及父类的成员,除非显示的调用父类的成员,使用base
如图所示:子类没有继承父类的私有字段,父类的私有字段只能在父类中使用。
4、子类,有没有继承父类的构造函数?
子类并没有直接继承父类的构造函数,因为创建子类对象的时候,没办法直接调用父类的构造函数。
但是,子类会【默认调用】父类无参的构造函数?(因为父类有可能要在自己的构造函数中,对自己的成员进行初始化),如果我们在父类中,提供了其他有参数的构造函数,子类就调用不到默认无参数的构造函数了,所以子类会报错。
如下图所示:在Programmer()类中加入了有参的构造函数,因此创建对象的时候必须要加入参数要想,不加入参数如下解决方案。
4.2解决方案
在Programmer()类中加入无参的构造函数,子类优先调用父类的无参的构造函数,因此这能够解决这中错误。
2、通过base:显示的调用父类的构造函数。
5.继承的一些规定
1、c#是一个单继承的思想。一个子类只能有一个父类。单根性
2、如果一个类,没有显示的继承别的类,那么这个类,默认就继承了object。顶级的父类
如果一个类,继承了别的类,那么这个类,同样也继承object。【object是所有引用类型的父类。】
3、继承的传递性,
2.类型转换
1.里氏替换原则:
1.子类可以赋值给父类。
2.如果一个父类指向的是一个子类对象,则可以将这个父类转化为这个子类。
3、转换之前必须确定父类到底指向的是哪一个子类对象,只能转成指向的那个子类对象,转成其他的,会抛异常。如下图所示不能强转为其他子类。
3.关键字 is as
关键字:
1、is:判断父类装的【指向】是否是对应的子类对象
2、as:不判断,直接转,如果转换成功,则返回对应的对象,否则返回一个null
is:判断父类指向的类型是否是相应子类对象。
as: 将person类型转换为teacher类,如果转换失败则返回null,不会抛异常。