《C#图解教程》读书笔记第7章——类和继承

来源:互联网 发布:登陆阿里云服务器 编辑:程序博客网 时间:2024/05/16 11:41

这本书讲解C#语言十分详细,我将其中的重要内容整理成条款,以备忘。


 

 

1.      派生类不能删除它继承的任何成员,但可以通过new修饰符隐藏它们。若要隐藏一个基类成员,需要在派生类中声明一个相同名称,相同类型的成员,若是方法则需签名相同,但不包括返回值。要让编译器知道是故意隐藏继承的成员,使用new修饰符。若要在派生类中访问被隐藏的基类成员,可以使用base表达式。

 

2.      派生类的引用指向整个派生类的对象(包括基类的对象加上派生类附加的成员),通过类型转换运算符,当有一个派生类对象的引用时,就可以获取该对象基类部分的引用。在没有虚成员被派生类覆写的情况下,通过基类部分的引用,只能访问派生类对象基类部分的成员派生类附加的(即派生类自己的)成员对其是不可见的

 

3.      只有使用派生类对象的基类引用调用被覆写过(override)的方法时才会引发多态,若方法没有被override,则情况同第2条所述。关于virtualoverride修饰符:1.覆写和被覆写的方法必须有相同的可访问性2.不能覆写static方法或非虚方法;3.方法、属性、索引和事件都可以被声明为virtualoverride

 

4.      使用基类的引用调用被覆写的虚方法意味着使基类引用的访问权“提升至”派生类内,直到继承层次中被标记为override最高派生级别版本,如果在更高的派生级别还有该方法的其他声明,但没有被标记为override,则它们不会被调用

 

5.      派生类只能override所在的继承层次中直接父类的被标记为virtualoverrideabstract的成员。

 

6.      执行构造函数时编译器首先执行基类的构造函数,以此类推执行到System.Object类为止,当前类的构造函数是最后被执行。当一个对象被创建(分配内存)后,首先初始化对象的所有实例成员然后是一系列构造函数的执行

 

7.      不推荐在构造函数中调用虚方法,因为这有可能会导致在派生类完全初始化之前调用派生类的覆写方法

 

8.      当对象被构造时,基类的无参构造函数被调用,可以在构造函数初始化语句中使用base来指定使用一个特定的基类构造函数而不是基类的无参构造函数;还可以通过this来指定本类中另一个构造函数进行初始化,但无论base还是this括号里面的参数列表都应该和相应的构造函数参数列表相对应。注意:即便使用了this,构造函数的执行仍旧是逐级递推到Object然后反向逐一执行,还有,thisbase不能同时修饰一个构造函数。

 

9.      类的访问级别只有publicinternal,默认为internal,除非在类声明中显示地指定为public,程序集外部的代码不能访问该类,标记为public的类可以被系统中任何程序集中的代码访问。

 

10.  C#允许从在不同的程序集(项目)中定义基类和派生类(注意程序集修改后要重新编译或重新生成解决方案),应满足:基类必须声明为public,必须在Visual Studio工程中添加对包含该基类的程序集的引用。注意:添加程序集引用是告诉编译器所需的类型在哪里被定义,但增加using指令允许你引用此程序集中其他的类而不必使用他们的完全限定名

 

11.  基类的private成员不能被继承,类中的每个成员都必须指定成员访问级别,若不显式指定,则隐式为private,另外,若一个的访问性限于它所在的程序集(即为Internal),那么类的成员也被不能在程序集的外部被访问,无论它们的访问修饰符是什么

 

12.  任何类的private成员只对它自己的类或它的嵌套类的成员可见。标记为internal的成员对同一程序集内部的任何类的成员可见,但对程序外部的类不可见。protected internal protectedinternal并集,而非交集。(详见P127的表7-2)

 

13.  抽象成员的实现由分号代替,在派生类的实现中必须被override修饰,并且只能被声明在抽象类中。能被声明为abstract的成员有方法、属性、事件、索引。

 

14.  抽象(abstract)类是用来被继承的,它可以派生自另一个抽象类,任何派生自抽象类的类必须使用override实现该类所有抽象成员,否则派生类也必须是抽象类,即类中有一个抽象成员就须声明为抽象类,一个抽象类可以包含抽象成员也可以包含普通带实现的实例成员

 

15.  密封(sealed)类只能用作独立的类,不能被继承。

 

16.  静态(static)类中的所有成员必须是静态的,不能继承静态类,它们是密封的静态类可以有一个静态构造函数,但不能有实例构造函数,和抽象类相同,不能创建静态类的实例

 

17.  C# 3.0增加了扩展方法允许在保持原有类型不做任何改变的情况下,对相同或不同的程序集内的方法进行扩展,从而可以从容地对第三方程序集进行扩展,并能在原有类型的实例自身上调用该方法。

 

18.  扩展方法必须声明在非泛型或非嵌套的静态类中,本身必须为static,必须包括this作为它的第一个参数类型,并在后面跟着它所要扩展的类的名称。另外,扩展可以被继承,对System.Object的扩展将能被所有类型继承。

 

19.  外部方法是在声明中没有实现并由分号代替实现的方法,实现多是由C#之外的语言编写,须有staticextern修饰符,方法的实现通常由DllImport特性引入,通常它包含所引用的外部方法的动态连接库的位置。要使用DllImport特性必须要using System.Runtime.InteropServices; 这个特性可以让我们调用非托管代码,可以使用DllImport特性引入对Win32API函数的调用。

 

20.   抽象类也有构造函数,如果我们自己没有定义的话,编译器会为我们生成一个默认的构造函数。若不提供访问限定符,则默认为protected访问级别。这样设计是因为抽象类需要被其他类继承,而这些子类需要被实例化,实例化子类时需要调用子类的构造函数,而在默认情况下,调用子类构造函数前先要调用基类的构造函数的,非常类似于非抽象类。另外,子类在实例化时:只会调用所有父类的无参构造函数,含参构造函数只能显式被调用。这种情况并不局限于抽象类,也适用于所有继承情况。