《C#图解教程》读书笔记第7章——类和继承
2009-09-04 00:24
267 查看
这本书讲解
C#
语言十分详细,我将其中的重要内容整理成条款,以备忘。
1.
派生类不能删除它继承的任何成员,但可以通过
new
修饰符隐藏它们。若要隐藏一个基类成员,需要在派生类中声明一个相同名称,相同类型的成员,若是方法则需签名相同,但不包括返回值
。要让编译器知道是故意隐藏继承的成员,使用
new
修饰符。若要在派生类中
访问被隐藏的基类成员
,可以使用
base
表达式。
2.
派生类的引用指向整个派生类的对象
(
包括基类的对象加上派生类附加的成员
)
,通过类型转换运算符,当有一个派生类对象的引用时,就可以获取该对象基类部分的引用。在没有虚成员被派生类覆写的情况下
,通过基类部分的引用,只能
访问派生类对象基类部分的成员
,派生类附加的
(
即派生类自己的
)
成员对其是不可见的
。
3.
只有使用派生类对象的基类引用调用被覆写过
(override)
的方法时才会引发多态
,若方法没有被
override
,则情况同第
2
条所述。关于
virtual
和
override
修饰符:
1.
覆写和被覆写的方法必须有相同的可访问性
;
2.
不能覆写
static
方法或非虚方法;
3.
方法、属性、索引和事件都可以被声明为
virtual
和
override
。
4.
使用基类的引用调用被覆写的虚方法意味着使基类引用的访问权“提升至”派生类内,直到继承层次中被标记为
override
的最高派生级别版本
,如果在更高的派生级别还有该方法的其他声明,但没有被标记为
override
,则它们不会被调用
。
5.
派生类只能
override
所在的继承层次中它直接
父类的
被标记为
virtual
、
override
或
abstract
的成员。
6.
执行构造函数时编译器首先执行基类
的构造函数,以此类推执行到
System.Object
类为止,当前类的构造函数是最后被执行
的
。当一个对象被创建
(
分配内存
)
后,首先初始化对象的所有实例成员
,然后是一系列构造函数的执行
。
7.
不推荐在构造函数中调用虚方法,因为这有可能会导致在派生类完全初始化之前
调用派生类的覆写方法
。
8.
当对象被构造时,基类的无参
构造函数被调用,可以在构造函数初始化语句中使用
base
来指定使用一个特定
的基类构造函数而不是基类的无参构造函数;还可以通过
this
来指定本类中另一个构造函数
进行初始化,但无论
base
还是
this
括号里面的参数列表都应该和相应的构造函数参数列表相对应。注意
:即便使用了
this
,构造函数的执行仍旧是逐级递推到
Object
然后反向逐一执行,还有,
this
和
base
不能同时修饰一个构造函数。
9.
类的访问级别只有
public
和
internal
,默认为
internal
,除非在类声明中显示地指定为
public
,程序集外部的代码不能访问该类,标记为
public
的类可以被系统中任何程序集中的代码访问。
10.
C#
允许从在不同的程序集
(
项目
)
中定义基类和派生类
(
注意程序集修改后要重新编译或重新生成解决方案
)
,应满足:基类必须声明为
public
,必须在
Visual Studio
工程中添加对包含该基类的程序集的引用。注意:添加程序集引用是告诉编译器所需的类型在哪里被定义
,但增加
using
指令允许你引用此程序集中其他的类而不必使用他们的完全限定名
。
11.
基类的
private
成员不能被继承,类中的每个成员都必须指定成员访问级别,若不显式指定,则隐式为
private
,另外,若一个类
的访问性限于它所在的程序集
(
即为
Internal)
,那么类的成员也被不能在程序集的外部被访问,无论它们的访问修饰符是什么
。
12.
任何类的
private
成员只对它自己的类或它的嵌套类的成员可见。标记为
internal
的成员对同一程序集内部的任何类
的成员可见,但对程序
集
外部
的类不可见。
protected internal
是
protected
和
internal
的并集
,而非交集。
(
详见
P127
的表
7-2)
13.
抽象成员的实现由分号代替
,在派生类的实现中必须被
override
修饰,并且只能被声明在抽象类中。能被声明为
abstract
的成员有方法、属性、事件、索引。
14.
抽象
(abstract)
类是用来被继承的,它可以派生自另一个抽象类,任何派生自抽象类的类必须使用
override
实现该类所有
的抽象
成员,否则派生类也必须是抽象类,即类中有一个抽象成员就须声明为抽象类
,一个抽象类可以包含抽象成员
也可以包含普通带实现的实例成员
。
15.
密封
(sealed)
类只能用作独立的类,不能被继承。
16.
静态
(static)
类中的所有成员必须
是静态的,不能继承静态类,它们是密封的
,静态类可以有一个静态
构造函数,但不能有实例
构造函数,和抽象类相同,不能创建静态类的实例
。
17.
C# 3.0
增加了扩展方法允许在保持原有类型不做任何改变的情况下,对相同或不同的程序集内的方法进行扩展,从而可以从容地对第三方程序集进行扩展,并能在原有类型的实例自身上调用该方法。
18.
扩展方法必须声明在非泛型或非嵌套的静态类
中,本身必须为
static
,必须包括
this
作为它的第一个参数类型,并在后面跟着它所要扩展的类的名称。另外,扩展可以被继承
,对
System.Object
的扩展将能被所有类型继承。
19.
外部方法是在声明中没有实现并由分号代替实现的方法,实现多是由
C#
之外的语言编写,须有
static
和
extern
修饰符,方法的实现通常由
DllImport
特性引入,通常它包含所引用的外部方法的动态连接库的位置。要使用
DllImport
特性必须要
using System.Runtime.InteropServices;
这个特性可以让我们调用非托管代码,可以使用
DllImport
特性引入对
Win32
API
函数的调用。
20.
抽象类也有构造函数
,如果我们自己没有定义的话,编译器会为我们生成一个默认的构造函数。若不提供访问限定符,则默认为protected
访问级别。这样设计是因为抽象类需要被其他类继承,而这些子类需要被实例化,实例化子类时需要调用子类的构造函数,而在默认情况下,调用子类构造函数前先要调用基类的构造函数的,非常类似于非抽象类。另外,子类在实例化时:只会调用所有父类的无参
构造函数,含参构造函数只能显式被调用
。这种情况并不局限于抽象类,也适用于所有继承情况。
C#
语言十分详细,我将其中的重要内容整理成条款,以备忘。
1.
派生类不能删除它继承的任何成员,但可以通过
new
修饰符隐藏它们。若要隐藏一个基类成员,需要在派生类中声明一个相同名称,相同类型的成员,若是方法则需签名相同,但不包括返回值
。要让编译器知道是故意隐藏继承的成员,使用
new
修饰符。若要在派生类中
访问被隐藏的基类成员
,可以使用
base
表达式。
2.
派生类的引用指向整个派生类的对象
(
包括基类的对象加上派生类附加的成员
)
,通过类型转换运算符,当有一个派生类对象的引用时,就可以获取该对象基类部分的引用。在没有虚成员被派生类覆写的情况下
,通过基类部分的引用,只能
访问派生类对象基类部分的成员
,派生类附加的
(
即派生类自己的
)
成员对其是不可见的
。
3.
只有使用派生类对象的基类引用调用被覆写过
(override)
的方法时才会引发多态
,若方法没有被
override
,则情况同第
2
条所述。关于
virtual
和
override
修饰符:
1.
覆写和被覆写的方法必须有相同的可访问性
;
2.
不能覆写
static
方法或非虚方法;
3.
方法、属性、索引和事件都可以被声明为
virtual
和
override
。
4.
使用基类的引用调用被覆写的虚方法意味着使基类引用的访问权“提升至”派生类内,直到继承层次中被标记为
override
的最高派生级别版本
,如果在更高的派生级别还有该方法的其他声明,但没有被标记为
override
,则它们不会被调用
。
5.
派生类只能
override
所在的继承层次中它直接
父类的
被标记为
virtual
、
override
或
abstract
的成员。
6.
执行构造函数时编译器首先执行基类
的构造函数,以此类推执行到
System.Object
类为止,当前类的构造函数是最后被执行
的
。当一个对象被创建
(
分配内存
)
后,首先初始化对象的所有实例成员
,然后是一系列构造函数的执行
。
7.
不推荐在构造函数中调用虚方法,因为这有可能会导致在派生类完全初始化之前
调用派生类的覆写方法
。
8.
当对象被构造时,基类的无参
构造函数被调用,可以在构造函数初始化语句中使用
base
来指定使用一个特定
的基类构造函数而不是基类的无参构造函数;还可以通过
this
来指定本类中另一个构造函数
进行初始化,但无论
base
还是
this
括号里面的参数列表都应该和相应的构造函数参数列表相对应。注意
:即便使用了
this
,构造函数的执行仍旧是逐级递推到
Object
然后反向逐一执行,还有,
this
和
base
不能同时修饰一个构造函数。
9.
类的访问级别只有
public
和
internal
,默认为
internal
,除非在类声明中显示地指定为
public
,程序集外部的代码不能访问该类,标记为
public
的类可以被系统中任何程序集中的代码访问。
10.
C#
允许从在不同的程序集
(
项目
)
中定义基类和派生类
(
注意程序集修改后要重新编译或重新生成解决方案
)
,应满足:基类必须声明为
public
,必须在
Visual Studio
工程中添加对包含该基类的程序集的引用。注意:添加程序集引用是告诉编译器所需的类型在哪里被定义
,但增加
using
指令允许你引用此程序集中其他的类而不必使用他们的完全限定名
。
11.
基类的
private
成员不能被继承,类中的每个成员都必须指定成员访问级别,若不显式指定,则隐式为
private
,另外,若一个类
的访问性限于它所在的程序集
(
即为
Internal)
,那么类的成员也被不能在程序集的外部被访问,无论它们的访问修饰符是什么
。
12.
任何类的
private
成员只对它自己的类或它的嵌套类的成员可见。标记为
internal
的成员对同一程序集内部的任何类
的成员可见,但对程序
集
外部
的类不可见。
protected internal
是
protected
和
internal
的并集
,而非交集。
(
详见
P127
的表
7-2)
13.
抽象成员的实现由分号代替
,在派生类的实现中必须被
override
修饰,并且只能被声明在抽象类中。能被声明为
abstract
的成员有方法、属性、事件、索引。
14.
抽象
(abstract)
类是用来被继承的,它可以派生自另一个抽象类,任何派生自抽象类的类必须使用
override
实现该类所有
的抽象
成员,否则派生类也必须是抽象类,即类中有一个抽象成员就须声明为抽象类
,一个抽象类可以包含抽象成员
也可以包含普通带实现的实例成员
。
15.
密封
(sealed)
类只能用作独立的类,不能被继承。
16.
静态
(static)
类中的所有成员必须
是静态的,不能继承静态类,它们是密封的
,静态类可以有一个静态
构造函数,但不能有实例
构造函数,和抽象类相同,不能创建静态类的实例
。
17.
C# 3.0
增加了扩展方法允许在保持原有类型不做任何改变的情况下,对相同或不同的程序集内的方法进行扩展,从而可以从容地对第三方程序集进行扩展,并能在原有类型的实例自身上调用该方法。
18.
扩展方法必须声明在非泛型或非嵌套的静态类
中,本身必须为
static
,必须包括
this
作为它的第一个参数类型,并在后面跟着它所要扩展的类的名称。另外,扩展可以被继承
,对
System.Object
的扩展将能被所有类型继承。
19.
外部方法是在声明中没有实现并由分号代替实现的方法,实现多是由
C#
之外的语言编写,须有
static
和
extern
修饰符,方法的实现通常由
DllImport
特性引入,通常它包含所引用的外部方法的动态连接库的位置。要使用
DllImport
特性必须要
using System.Runtime.InteropServices;
这个特性可以让我们调用非托管代码,可以使用
DllImport
特性引入对
Win32
API
函数的调用。
20.
抽象类也有构造函数
,如果我们自己没有定义的话,编译器会为我们生成一个默认的构造函数。若不提供访问限定符,则默认为protected
访问级别。这样设计是因为抽象类需要被其他类继承,而这些子类需要被实例化,实例化子类时需要调用子类的构造函数,而在默认情况下,调用子类构造函数前先要调用基类的构造函数的,非常类似于非抽象类。另外,子类在实例化时:只会调用所有父类的无参
构造函数,含参构造函数只能显式被调用
。这种情况并不局限于抽象类,也适用于所有继承情况。
相关文章推荐
- 《Python基础教程》读书笔记(2)之第7章更加抽象(关键词:Python/面向对象/多态/封装/方法/继承)
- 《Android开发艺术探索》读书笔记 (7) 第7章 Android动画深入分析
- 《JS高级程序设计》第6章读书笔记:继承对象(四)寄生组合式继承
- 读书笔记:maven入门-聚合与继承
- 读书笔记《Effective C++》条款33:避免遮掩继承而来的名称
- 读书笔记--C++程序设计(第2版)--11.6多重继承(与虚基类)
- 《HeadFirst设计模式》读书笔记-第7章-适配器模式
- C#2008与.NET 3.5 高级程序设计读书笔记(6)--继承和多态
- 《数据结构与算法:C#语言描述》第7章读书笔记
- 《Effective C++》读书笔记之item32:确定你的public继承塑模出is-a关系
- 《Effective C++》读书笔记之item39:明智而审慎地使用private继承
- 《Effective C++》读书笔记之item40:明智而审慎地使用多重继承
- 《C#图解教程》读书笔记第17章——接口
- 读书笔记_Effective_C++_条款三十七:绝不重新定义继承而来的缺省参数值
- 多重继承——《C++编程风格》读书笔记(七)
- 读书笔记-Thinking in C++-第7章 函数重载和默认参数Function Overloading &Default Arguments
- 20161028 Python 读书笔记之类、多态、继承、封装
- 《C和指针》 读书笔记 -- 第7章 函数
- 《疯狂java讲义2》读书笔记——面向对象的三大特性之一:继承(已更新完)
- JavaScript高级程序设计 (6章 继承)---读书笔记