1. 继承的特性
传递性和单一继承性
2. 访问修饰符
父类中的成员如果用public修饰,任何类都可以访问;如果用private修饰,它将作为私有成员,只有类本身可以访问,其他任何类都无法访问。在C#中,我们使用protected修饰符,使用这个访问修饰符的成员可以被其子类访问,而不允许其他非子类访问。
从上面的表中可以看出,父类中只有被“public”、“protected”、“internal”修饰的成员才可以被继承,这些成员包括任何父类的字段、属性、方法和索引器,但是父类的构造函数和析构函数是不能被子类继承的。如果要继承父类的构造函数,必须使用base关键字来实现。
注意:以上都是针对类中的成员谈继承性,至于为何不谈类的继承性原因是:在c#语言中;类只能被public或internal修饰,而这两中类都是可以被继承的,也就是说c#中的类都是可以继承的!
3. base关键字
C#中base关键字在继承中起到非常重要的作用,它可以和this关键字相比较,大家都知道this代表当前实例,那么base关键字代表父类,使用base关键字可以调用父类的构造函数、属性和方法。使用base关键字调用父类构造函数的语法如下:
子类构造函数:base(参数列表)
使用base关键字调用父类方法的语法如下:
base:父类方法();
构造函数使用base:
class A {
public int age;
public A(int s) {
this.age = s;
}
}
class B : A {
public string name;
public B(int s,string n) : base(s) {
this.name = n;
}
}
调用父类方法使用base:
class Program:A
{
static void Main(string[] args)
{
Program p = newProgram();
p.M();
}
public void M() {
Console.WriteLine( base.run());
}
}
class A {
public int age;
public string run() {
return "everybody can run!";
}
}
注意:使用base调用父类的方法时,不能用于静态(static)方法内!
4. this关键字
在类的方法里输入this关键字,在后面输入一个“.”符号后,系统就会把本类所能调用的法,非静态方法和变量都显示出来让你选择,提高了编码效率。这种情况下使用的this关键字代表本类。除了这种用法,this关键字还可以调用自己的构造方法。
5. 多态性
多态是指两个或者多个不同类的对象,调用同一个方法出现不同的结果。前面我们学习的方法重载,方法名完全相同,但是不同的对象调用时,由于参数不同,执行的结果是不相同的,就是多态的一种表现。(方法重载是多态的一种表现)
6. 虚拟方法实现多态性
在父类中用virtual关键字声明的方法在子类中可以重写,就是虚拟方法。虚拟方法语法如下:
访问修饰符 virtual 返回类型 方法名()
{
//方法体
}
理解:在c#中,父类的方法只有是virtual修饰下才能在被子类继承时重写该虚拟方法。而方法的重写会导致调用相同的方法产生不同的效果这一现象,这正好复合多态的定义。所以,方法重写也是多态的一种表现!
注意:父类中不是虚拟方法的不能在子类中重写,但是子类可以继承这些方法,也可以通过base调用这些方法。仅仅只是不能对这些方法重写而已!!
7. 抽象类和抽象方法
抽象方法是一个没有实现的方法,使用关键字abstract定义抽象方法,语法如下:
<访问修饰符> abstract 返回类型 方法();
例如:
public abstract void Cry();
注意:抽象类就是用abstract修饰的类,抽象类中可以有抽象方法,也可以有非抽象方法。而抽象方法不能存在与非抽象的类中,只有抽象类才能包含抽象方法。
注意:虚拟方法和抽象方法的区别在与:1)虚拟方法有方法体,可以有具体的实现。而抽象方法没有方法体。2)虚拟方法可以存在于抽象的类中,抽象方法只能存在于抽象类中。
在子类中实现基类的抽象方法或者虚拟方法,使用override关键字来重写方法,格式如下:
访问修饰符 override 返回类型 方法()
{
//方法体
}
注意:若子类继承自一个抽象类,必须实现这个抽象父类中的全部抽象方法,记住,是全部的抽象方法,不是全部的方法。再说,就算要重写抽象类中的非抽象方法,也得在这个方法有virtual修饰的前提下才能重写。
8. 接口
C#中规定一个派生类,只能有一个父类,但可以实现多重接口。
接口只包含行为的定义,不能有任何具体的实现。
注意:接口中只有成员方法,没有成员变量(字段)。
• 定义了接口后,就要在子类中实现。C#中通常把子类和父类的关系称为继承,子类和接口的关系称为实现。子类可以继承一个父类,可以实现多个接口。接口中不能定义构造函数,所以接口不能实例化。
• 注意:抽象类也不能实例化,抽象类中的抽象方法在子类中实现,虚拟方法在子类中可重写可不重写,成员变量通过子类对象来调用!
9. 显式接口实现
一个类可以实现多个接口,如果两个接口中有相同的方法名,那么同时实现这两个接口的类,就会出现不确定情形,在编写方法时,不知道该实现哪个接口的这个方法了。为了解决这个问题,C#提供了显式接口实现的技术,就是在方法名称前加上接口名称,用接口名称来限定该成员变量。
注意:实现接口中的抽象方法不能用关键词override.
而实现抽象类中的抽象方法或者重写虚拟方法都要用override关键字
interface A {
void run();
}
interface B {
void run();
}
class C : A, B {
void A.run(){
}
void B.run() {
}
}