目录
基类相关
- 基类和派生类
- 所有类都是object的派生类
class Myclass : MyBaseClass
- 派生类继承基类的所有成员,实例可以直接引用
- 可以对基类的成员进行隐藏,在派生类成员前面加上new 关键字,并且函数要签名相同,数据要类型相同
- 可以没有new关键字,但是编译器会给出警告
- 即使隐藏了基类的成员,但是还可以通过基类访问表达式进行访问,
base.Field1
- 在使用基类的变量存储派生类的对象引用时,调用的是该引用能看到的方法的实现。
MyBaseClass my =(MyBaseClass) new MyClass()
- 当使用基类引用访问派生类对象时,得到的是基类成员。(即使没有隐藏或者隐藏了)
虚方法
- 如果想让其调用派生类的成员方法,可以通过覆写,在基类的方法前面加关键字virtual,在派生类的方法前面加override,派生类和基类的方法有相同的签名和返回类型
- 这样当使用基类引用调用方法时,方法调用被传递到派生类并执行
- 覆写和被覆写的方法必须有相同的可访问性
- 不能覆写static方法或非虚方法
- 以下四种类型可以被声明为virtual和override
- 方法
- 属性
- 索引
- 事件
覆写标记为override的方法
- 覆写方法可以在继承的任何层次出现
- 当使用对象基类部分的引用调用一个覆写方法时,方法的调用被沿派生层次上溯执行,一直到标记为override的方法的最派生版本
- 如果在更高的派生级别有该方法的其他声明,但没有被标记为override,就不会被调用
- 我们也可以用同样的形式覆写其他成员类型
构造函数的执行
- 派生类对象有一部分是基类对象
- 要创建对象的基类部分,基类的一个构造函数被作为创建实例过程的一部分被调用
- 继承层次链中的每个类在执行它自己的构造函数体之前执行它的基类的构造函数
- 执行顺序
- 初始化实例成员
- 调用基类构造函数
- 执行实例构造函数的方法体
- 在构造函数中调用虚方法是极不推荐的。基类的构造函数被执行时,虚方法会调用派生类的覆写方法,但是派生类还没有完全初始化
构造函数初始化语句
- 可以让派生类使用一个指定的基类构造函数而不是无参数构造函数,必须在构造函数初始化语句中指定它
public MyDerivedClass(int x, string s) : base(s,x)
- 构造函数初始化语句由关键字base和要调用的基类构造函数的参数列表组成
- 第二种形式的构造函数初始化语句,使用关键字this并指明应该使用当前类的哪一个另外的构造函数
public MyClass(int x): this(x, "Using Default String")
- 应用场景,可以把类的所有构造函数的公共代码提取出来作为一个构造函数,被其他所有的构造函数作为构造函数初始化器使用
类访问修饰符
- 类的访问级别有两个,public 和 internal
- 标记为public的类可以被系统内任何程序集中的代码访问
- 标记为internal的类只能被它自己所在的程序集内的类看到, 这是默认的可访问级别
程序集间的继承
- C#允许从一个在不同的程序集内定义的基类派生类
- 基类必须被声明为public,这样才能被访问
- 必须在工程中包括对该基类的程序集的引用
- 为了不使用它们的完全限定名称,在源文件的顶部放置一个using指令,带上将要访问的类或类型所在的命名空间
- 增加对其他程序集的引用和增加using指令是两回事情
成员访问修饰符
- 访问对象可以按照和正在声明的类的关系分为四类
- 一个程序集,不继承于它的类
- 一个程序集,继承于它的类
- 不在同一个程序集,继承于它
- 不在同一个程序集,也不继承于它
- 所有显式声明在类中的成员之间互相可见,但是继承的成员可见,也不可见。
- 必须对每个成员指定成员访问级别,如果没有指定,默认为private
- 成员不能比它的类更可访问。
- private只能内部访问
- protected 只要是派生于它,都可以访问
- internal 只要是同一程序集,都可以访问
- protected internal 派生与同一程序集的并集
- public 四个部分都可以进行访问
抽象类与抽象成员
- 抽象类只能被继承,不能被实例化,只能作为基类
- 抽象类的成员可以是抽象成员和非抽象成员的任意组合
- 抽象类可以派生自另一个抽象类,不用实现其抽象成员
- 抽象成员没有实现代码块,以分号结尾,是被设计来覆写的函数成员
- 抽象成员用abstract标记
- 抽象成员只能声明在抽象类内
- 可以被声明为抽象的成员有以下几个,虚成员相同。都是函数成员
- 方法
- 属性
- 事件
- 索引
- 抽象成员必须在派生类中覆写,但是不用在abstract前面添加virtual
- 派生类中抽象成员的实现必须要添加overide关键字
- 数据成员不可以声明为abstract
密封类
- 在类前面加关键字sealed
- 它是一个独立的类,不能被用作基类
静态类
1.隐式密封的,不能继承自静态类
2. 可以有一个静态构造函数,但是没有实例构造函数
3. 类的所有成员必须是静态的
扩展方法
- 我们可以编写和声明它的类之外的类关联的方法
- 如果你不能访问代码,或该类是密封的,或有其他的设计原因使这些方法不能工作,不得不在另一个类中使用该类的公有可用成员编写一个方法
ExtendMyData.Average(md)
- 第二种形式
md.Average()
- 扩展方法重要的需求如下
- 声明扩展方法的类必须是static
- 扩展方法本身是公有静态的,public static
- 扩展方法必须包含关键字this作为第一个参数类型,并在后面跟上所扩展的类的名称