继承
OOP三大要素:封装/继承/多态
代码重用:is-a关系(继承)/has-a关系(包含)
继承:基类/派生类
继承保护了封装
派生类不能访问基类的私有成员
C#中一个类只有一个基类,也就是说不支持多重继承;
将类标记为sealed,类不允许被继承,封闭类,如String
C#结构总是隐式密封的,故结构不存在继承关系
在继承中使用base关键字控制基类的创建:
class p : Class3
{
public int j;
public p(int i, int k):base(k)
{
j = i;
}
}
为类增加了自定义构造函数,那么默认构造函数就移除了。
Protected关键字
可以被任何后代访问
对于实例对象而言,protected仍然是私有的,和private一样,是无法通过对象进行访问的。
Virtual&Override
子类通过override重写积累中virtual方法,virtual虚方法可以实现。
比如基类中Func为虚方法,则派生类A中可以重写override 方法Func,而以A为基类的派生类B,又可以重写Func,这时候如果把A中Func设置为密封的Sealed,则B中就不能够重写了。
抽象基类:abstract
当你定义没有提供默认实现,而必须在每个派生类中实现的成员时,使用抽象成员。
一个抽象基类中,可以同时存在virtual成员方法和abstract成员方法。
为什么需要abstract抽象方法,是因为在某些情况下,用virtual方法表述不清,因为virtual方法不是必须重写的,所以Circle可能重写了Shape的Draw()方法,而Rectangle没有重写,那么就会继承Shape的Draw方法,那么分别对二者调用Draw时就发现,Rectangle的Draw不太合理,因为是基于Shape的。引入abstract方法,就是强制重写。
抽象方法只能定义在抽象类中。
成员投影
如果派生类中定义的成员与定义在基类中的成员一致,那么派生类中的成员会覆盖掉基类中的版本,同时编译器会给出警告,解决方案:
1、修改基类成员为virtual
2、对成员添加new关键字,故意隐藏父类的版本。
如下:
基类派生类的转换原则
在基类引用中保存派生类型总是安全的,隐式转换。
显示转换:强制类型转换。
显示强制转换在运行时而不是在编译时发生,需要程序员对结果负责。需要引入结构化异常处理Try…Catch机制。
也可以使用as操作符,如果类型兼容,返回引用,不兼容返回null。
ClassA obj=B as ClassA;
Is操作符仍然需要显示强制转换。
If(B is ClassA)
…((ClassA)B).chengyuan;
用is判断之后,显然就不需要异常处理了。