C#高级编程 chapter 4 继承 读书笔记
C#高级编程 chapter 4 继承 读书笔记
1》 实现继承和接口继承
A》 实现继承 表示一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数;
B》 接口继承 表示一个类型只继承了函数的签名,没有继承任何实现代码。
C》 个人理解:实现继承就是一个子类继承了一个父类,而父类非接口,有关于各个函数的具体实现,子类可以扩充自己的功能,但是从
父类继承来的函数必须重写之以赋予其新的特性;接口继承,就是一个类实现了一个接口,只是被要求必须实现某些特性,但是没有被强制
指定具体的实现细节,这样有共性的不同类型可以通过接口继承来保持共性,并且实现个性。同时,我觉得接口继承在一定程度上提供了一
种类型划分的层次:接口属于类型的上层,而不同的子类处在下层,可以用一组上层类型来将不同的子类组织在一起。比如在实现LogRecord
的时候,有Redo,Undo等不同类型的LogRecord,但是都继承自LogRecord接口,用一个LogRecord数组,可以将不同的日志记录组织在一起。
2》 多重继承
A》 C#的多重继承之允许类型派生于多个接口。这说明,C#类可以派生于另一个类和多个接口。因为System.Object是一个公共积累,所以
每个C#类(Object除外)都有一个积累,还可以有任意多个接口。
3》 结构和类
A》 使用结构的一个限制是结构不支持继承,但是每个机构都自动派生于System.ValueType。不能建立结构的类型层次,但是结构可以实
现接口。换言之,结构不支持实现继承,但是支持接口继承。
B》·1 结构总是派生于System.ValueType,它们还可以派生于任意多个接口;
·2 类总是派生于用户选择的另一个类,它们还可以派生于任意多个接口。
4》 实现继承
A》 class MyDerivedClass : MyBaseClass {}
B》 public class MyDerivedClass : MyBaseClass,IInterface1,IInterface2 {}
C》 public struct MyDerivedStruct : IInterface1,IInterface2 {}
5》 虚方法
把一个基类函数声明为virtual,该函数就可以在任何派生类中重写了;
在派生类中,重写虚方法的时候,要使用override关键字显式声明。
6》 隐藏方法
接5》中的方法重写,如果原方法和重写的方法没有声明virtual和override的时候,就产生了隐藏方法,派生类中的方法将原方法隐藏,
这是不安全的,编译会有warning,要实现隐藏方法应该的做法是:使用new关键字,即 public new int MyOldMethod(){};
7》 调用方法的基类版本
C#中没有super关键字,用的是base,但用法一样:base.MyOldMethod()。
注意:可以使用base.<MethodName>()语法调用基类中的任何方法,不必再同一个方法的重载中调用它。
8》 抽象类和抽象函数
C#允许吧类和函数声明为abstract,抽象类不能实例化,而抽象函数没有执行代码,必须在非抽象的派生类中重写(显然,抽象函数也是
虚拟的)
9》 密封类和密封方法
c#允许把类和方法声明为sealed。对于类来书,这表示不能被继承;对于方法来说,这表示不能被重写。
可以把C#中的sealed当做Java中的final。(但是sealed对成员变量无效,这样的修饰认为是非法的,而final可以对成员变量修饰)
10》 派生类的构造函数
默认的构造函数在整个层次结构中的使用:编译器首先找到类A试图实例化的构造函数,这个构造函数首先要做的是为其直接基类(类B)
运行构造函数,然后类B的构造函数运行其直接基类(类C)的构造函数……直到System.Object,System.Object没有任何基类,所以它的构
造函数直接运行,然后依次返回,最终类A的实例就已经成功地构造和初始化了。
11》 修饰符
A》 可见性修饰符
----------------------------------------------------------------------------------------------------------
修饰符 | 应用于 | 说明
----------------------------------------------------------------------------------------------------------
public | 所有的类型或成员 | 任何代码均可以访问该方法
----------------------------------------------------------------------------------------------------------
protected | 类型和内嵌类型的所有成员 | 只有派生的类型能访问该方法
----------------------------------------------------------------------------------------------------------
internal | 类型和内嵌类型的所有成员 | 只能在包含它的程序集中访问该方法
----------------------------------------------------------------------------------------------------------
private | 所有的类型或成员 | 只能在它所属的类型中访问该方法
----------------------------------------------------------------------------------------------------------
protected internal | 类型和内嵌类型的所有成员 | 只能在包含它的程序集和派生类型的代码中访问该方法
----------------------------------------------------------------------------------------------------------
不能把类型定义为protected、private和protected internal,因为这些修饰符对于包含在命名空间中的类型来说是没有意义的。因此,
这些修饰符只能应用于成员。但是,可以利用这些修饰符定义潜逃的类型(即包含在其他类型中的类型),因为在这种情况下,类型也具有
成员的状态。
B》 其他修饰符
----------------------------------------------------------------------------------------------------------
修饰符 | 应用于 | 说明
----------------------------------------------------------------------------------------------------------
new | 函数成员 | 成员用相同的签名隐藏继承的成员
----------------------------------------------------------------------------------------------------------
static | 所有成员 | 成员不在类的具体实例上执行
----------------------------------------------------------------------------------------------------------
virtual | 仅类和函数成员 | 成员可以由派生类重写
----------------------------------------------------------------------------------------------------------
abstract | 仅函数成员 | 虚拟成员定义了成员的签名,但没有提供实现代码
----------------------------------------------------------------------------------------------------------
override | 仅函数成员 | 成员重写了继承的虚拟或抽象成员
----------------------------------------------------------------------------------------------------------
sealed | 类 | 成员重写了继承虚拟成员,但继承该类的任何类都不能重
| | 写该成员。该修饰符必须与override一起使用
----------------------------------------------------------------------------------------------------------
extern | 仅静态[DllImport]方法 | 成员在外部用另一种语言实现
----------------------------------------------------------------------------------------------------------
internal与public类似,但访问仅限于同一个程序集中的其他代码,换言之,在同一个程序中编译的代码。internal能保证同一程序中编
写的其他类都能访问某一成员,但是程序之外的其他代码不能访问。
protected internal合并和protected和internal,但这是一种OR合并,而不是AND合并。protected internal成员在同一个程序集的任何
代码中都可见,在派生类中也可见,甚至在其他程序集中也可见。
12》 接口
A》 接口特性
1· 声明接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的执行方式。一般情况下,接口中只能包含方法、属
性、索引器和事件的声明;
2· 不能实例化接口,它只能包含其成员的签名。接口不能有构造函数或字段;
3· 接口定义也不允许包含有运算符重载,只是因为接口通常是公共契约,包含运算符重载还引起一些与其他.NET语言的不兼容的
问题;
4· 接口定义中海不允许声明成员上的修饰符;
5· 接口成员是公共的,不能声明为虚拟或静态。
B》 接口引用完全可以看做是类引用--但接口引用的强大之处在于,它可以引用任何实现该接口的类。(如最开始所说,可以用接口来组
织所有实现该接口的那些类)。
C》 派生的借口
接口可以彼此继承,其方式与类的继承相似。
-------------------------------------------------------------------------------------------------------------------------
第一次认真地把这些东西看一遍,总结一下,虽然简单、琐屑,但是很基础。
学习C#其实是用的代码催动的做法,草草看了基本的语法,然后就直接上了几千行的代码,做源码分析,虽然收获不少,但是有点囫囵吞
枣的感觉,基础不扎实,乘着这次写代码的机会,好好把C#学习一遍。
明显感觉很多东西之前都漏掉了,唉,杯具下……
加油,每天进步一点点!