【读书笔记】C#高级编程 第四章 继承

时间:2021-12-07 07:49:36

(一)继承的类型

1、实现继承和接口继承

在面向对象的编程中,有两种截然不同的继承类型:实现继承和接口继承。

实现继承:表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。在实现继承中,派生类型采用基类型的每个函数代码,除非在派生类型的定义中指定重写某个函数的实现代码。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承非常有用。

接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。在需要制定该类型具有某些可用的特性时,最好使用这种类型的继承。

2、多重继承

C#不支持多重实现继承,但允许类型派生自多个接口——多重接口继承。准确地说,因为System.Object是一个公共的基类,所以每个C#类(除Object类)都有一个基类,还可以有任意多个基接口。

3、结构和类

结构不支持实现继承,但支持接口继承。

定义结构和类可以总结为:

结构总是派生自System.ValueType,它们还可以派生自任意多个接口。

类总是派生自System.Object或用户选择的另一个类,它们还可以派生自任意多个接口。

(二)实现继承

声明派生自另一个类的类,语法如下:

例子:

以下代码创建了MyBaseClass类、MyClass类,其中MyClass类派生自MyBaseClass类

class MyBaseClass { } class MyClass : MyBaseClass { }

如果类(或结构)也派生自接口,则用逗号分隔列表中的基类和接口:

class MyClass : MyBaseClass,IInterface1,IInterface2 { }

对于结构,语法如下:

public struct MyStruct: IInterface1, IInterface2 { }

1、虚方法

把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:

class MyBaseClass { public virtual string VirtualMethod() { return "虚方法"; } }

在C#中,函数在默认情况下不是虚拟的,但(出构造函数以外)可以显式地声明为virtual。同时C#要求在派生类在重写基类中的函数时,要使用override关键字显式声明:

class MyClass : MyBaseClass, IInterface1, IInterface2 { public override string VirtualMethod() { return "重写了基类的虚方法"; } }

2、隐藏方法

如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和override,派生类方法就会隐藏基类方法。

例子:

以下代码中,基类和派生类有一个相同的方法ShowName,当我们需要隐藏基类中的方法时应该显示地使用关键字new,否则编译器会发出警告。隐藏了基类方法,我们不能通过派生类访问基类方法,只能通过派生类自己访问。

class MyBaseClass { public void ShowName(string name) { Console.WriteLine(name); } } class MyClass : MyBaseClass, IInterface1, { public new void ShowName(string name) { Console.WriteLine("派生类"+name); } }

在大多数情况下,我们应该重写方法,而不是隐藏方法,因为隐藏方法会造成对于给定类的实例调用错误方法的危险。

3、调用函数的基类版本

C#有一种特殊的语法用于从派生类中调用方法的基类版本:base.<MethodName>()。

例子:

以下代码在基类打印出名字的基础上,再打一行欢迎语

class MyBaseClass { public virtual void ShowName(string name) { Console.WriteLine(name); } } class MyClass : MyBaseClass, IInterface1, IInte { public override void ShowName(string name) { base.ShowName(name); Console.WriteLine("欢迎您的光临!"); } }

运行以上代码,结果如下:

4、抽象类和抽象函数