一步一步学c#(四):继承

时间:2021-08-14 16:44:28

继承

1·继承的类型

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

实现继承:表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。

接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。

结构和类

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

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

实现继承

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

一步一步学c#(四):继承

如果在定义中没有指定基类,编译器就会默认为System.object是基类,所以下面的两段代码结果一样:

一步一步学c#(四):继承

虚方法

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

一步一步学c#(四):继承

可以把属性声明为virtual,要在定义中添加关键字virtual:

一步一步学c#(四):继承

成员字段和静态函数都不能声明为virtual,因为这个概念只对类中的实例函数有意义。

调用函数的基类版本

c#有一种特殊的语法用于从派生类中调用方法的基类版本:base.<MethodName>().假定派生自类中的一个方法要返回基类的方法90%的返回值,就可以使用语法:

一步一步学c#(四):继承

}

密封类和密封方法

c#允许把类和方法声明为sealed。对于类,表示不能继承该类,对于方法,表示不能重写该方法:

一步一步学c#(四):继承

在层次结构中添加无参数的构造函数

假定把每个人的名字初始化为字符串“<no name>”而不是null。就可以修改GenericCostomer中的代码:

一步一步学c#(四):继承

在层次结构中添加带参数的构造函数

仅在顾客提供其姓名时才实例化顾客,带一个参数的GenericCustomer构造函数;

一步一步学c#(四):继承

目前是正常运行,但是,编译器试图为派生类创建默认构造函数时,会产生一个错误,需要派生类提供一个构造函数,来避免这个编译错误:
一步一步学c#(四):继承

可见性修饰符

一步一步学c#(四):继承

类型定义可以是内部或共有的,这取决于是否希望在类型包含的程序集外部访问它:

一步一步学c#(四):继承

不能把类型定义为protected,private和protected internal,因为这些修饰符对于包含在名称空间中的类型没有意义。

其他修饰符

一步一步学c#(四):继承

接口

下面列出Microsoft预定义的一个接口system。idisposabl的完整定义。

一步一步学c#(四):继承

声明接口在语法上与声明抽象类完全相同,接口只能包含方法,属性,索引器和事件的声明。

定义和实现接口

开发一个循环接口继承规范的小例子来说明如何定义和使用接口:

此例建立在银行账户的基础上。

首先,需要定义IBankAccount接口:

一步一步学c#(四):继承

下面是第一个,一个由Royal Bank of Venus运行的存款账户:

一步一步学c#(四):继承

一步一步学c#(四):继承

为了说明不同的类如何实现相同的接口,下面假定Planetary Bank of Jupiter还实现一个类,GoldAccount来表示其银行账户中的一个:
一步一步学c#(四):继承

测试他们用一些using语句:
一步一步学c#(四):继承

}

执行结果:
一步一步学c#(四):继承

派生的接口

定义一个新的接口ITransferBankAccount来说明,该接口的功能与IBankAccount相同,只是定义了一个方法,把资金直接转到另一个账户:

一步一步学c#(四):继承

下面说明ITransferBankAccount:假定Planetary Bank of jupiter还提供了一个当前账户,

一步一步学c#(四):继承

验证该类:

一步一步学c#(四):继承

一步一步学c#(四):继承