5 继承
1 为什么要有继承
继承(加 上封装和多态性)是面向对象的编程的三个主要特性(也称为“支柱”)之一。继承用于创建可重用、扩展和 修改在其他类中定义的行为的新类。其成员被继承的类称为“基类”,继承这些成员的类称为“派生类”。利用继承可以提高编程效率
如果一个类B继承自另一个类A,就把这个B称为"A的子类",而把A称为"B的父类"。继承可以使得子类具有父类的各种非私有属性和方法,而不需要再次编写相同 的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。
2 继承的类型
在面向对象编程中,有两种截然不同的继承:实现继承和接口继承
- 实现继承:表示一个类型(派生类)派生于一个基类型(基类) ,派生类拥有基类的所有除了构造函数和析构函数以外的成员。在实现继承中,派生类的每个函数都采用基类的实现代码,也可以在派生类中重写该函数的实现代码。常用在给现有的类添加功能,或者许多相关类型共享一组重要的公共的功能时。
- 接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。在需要指定该类具有某些可用的特性时,最好使用这种继承。
- 多重继承:C#不支持多重继承,而c#双允许派生于多个接口。这说明,C中的类可以派生于另一个类和任意多个接口。
3 实现继承
如果要声明一个类派生于另一类,可以使用下面的语法
class MyDriveredClass :MyBaseClass
{
//functions and datamembers here
}
如果类也派生于接口,可以在后面用逗号分隔基类和接口
class MyDriveredClass:MyBaseClass,Ininterface1,Inifterace2
{
//etc.
}
3.1 抽象类和抽象方法
如果希望禁止 通过 new 关键字直接进行实例化,可以将类声明为 abstract。如果这样做,则仅当从该类 派生新类时才能使用该类。抽象类可以包含一个或多个自身声明为抽象的方法签名。这些签名指定参数和返回 值,但没有实现(方法体)。抽象类不必包含抽象成员;但是,如果某个类确实包含抽象成员,则该类自身必须声明为抽象类。自身不是抽象类的派生类 必须为抽象基类中的任何抽象方法提供实现。
什 么是抽象类:不能被实例化的类称为抽象 类,抽象类是派生类的基类。
关键字:abstract
语法:
abstract class 类名
{
…………
}
1、一个抽象类可以同时包含抽象方法和非抽象 方法。
2、抽象方法只在派生类中真正实现,这表明抽象方法只存放函数原型,不涉及主体代码,
3、派生自抽象类的类需要实现其基类的抽象方法,才能实例化对象。
4、使用override关键子可在派生类中实现抽 象方法,经override声明重写的方法称为重写基类方法,其签名必须与override方法的签名相同。
5、基类实现抽象类,则派生类不需要重新实 现该抽象类。
6、抽象类并不仅仅只是一种实现技巧,它更代表一种抽象的概念,从而为所有的派生类确立一 种约定。
3.2 抽象方法和虚方法
基类将方法声 明为 virtual 时,派生类可以用自己的实现重写该方法。如果基类将成员声明为 abstract,则在直接继承自该类的任何非抽象类中都必须重写 该方法。如果派生类自身是抽象的,则它继承抽象成员而不实现它们。抽象成员和虚成员是多态性 的基础,多态性是面向对象的编程的第二个主要特性
虚方法(virtual)和抽象方法(abstract)的区别
1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
2. 抽象方法只能在抽象类中声明,虚方法不是。其实如果类包含抽象方法,那么该类也是抽象的,也必须声明为抽象的。
3. 抽象方法必须在派生类中重写,这一点跟接口类似,虚方法不必。
C#中的方法重写
关键 字:override
override关键字用于重写方法,具有override关键字修饰符的方法是 对基类中同名方法的新实现,基类中的同名方法必须声明为virtual或abstract类型。给基类中的方法添加virtual关 键字表示可以在派生类中重写它的实现。
1、 默认的C#方法并非virtual, 因此不能重写。
2、 基类方法的可访问级别并不因重写它的方法而改变,他们的访问修饰符相同。
3、new、static和virtual关键字不能与override访 问修饰符一同使用
关键字:virtual
C#中 提供virtual关键字,用于将方法定义为支持多态,用于对一个类中可修改的方法的声明,这种方法称为虚拟方法,派生类可以使用override关键字自由实现它们各自版本的虚拟方法
语法:
[访 问修饰符] virtual [返回值类型] 方法名称([参数列表])
{
//虚拟方法的 实现
}
1、virtual访问修饰符不能与static和override等访问修饰符一同使用
2、调用虚拟方法,在运行时系统会自动检查,以确定调调用了哪一个实现方法。
关键字:new
new访问修饰符用于显式隐藏继承自基类的成员,如果派生类成员与基类成员名称相同,new会 将派生类成员识别为一个全新成员。
1、在一个方法中同时使用new和override将会出错。
2、new访问修饰符的真正目的是为了隐藏基类方法。
3、如果将一个方法生命为new,它实际上并没有隐藏基类方法,并且 编译器也产生了警告,这时应该删除new。
3.3隐藏方法
如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有声明为virtural和override,派生类方法就会隐藏基类方法。
在大多数情况下,我们需要重写方法而不是隐藏方法。因为隐藏方法会存在为给定类型的实例调用错误方法的风险。
4 调用函数的基类版本
派生类构造函数并调用基类构造函数用:base.<MethodName>()