1、继承的类型
- 实现继承:一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数。
- 接口继承:一个类型只继承了函数的签名,没有继承任何实现代码。
2、C#是否支持多重继承?
- 开发C#的重要目标是简化健壮代码的编写工作,因此,不支持多重继承,
- C#允许类型派生自多个接口——多重接口继承
3、继承的语法结构
- 声明派生自另一个类
class MyClass: MyBaseClass
- 类派生于接口,则用逗号分隔接口
class MyClass: IInterface1, IInterface2
4、什么是虚方法?
- 将基类函数声明为virtual,就可以在任何派生类中重写该函数,
- 需要使用override关键字;也可以把属性声明为virtual。
class MyBaseClass { public virtual string MethodTest() {} }
5、隐藏方法
- 签名相同的方法在基类和派生类中都进行了声明,但没有声明为virtual或者override,派生类就会隐藏基类的方法。
- 在开发中,基类和派生类有相同名字的方法,但却没有任何关系,为了能正常编译,就要隐藏一个方法,会使用new关键字声明。
class MyClass: MyBaseClass { public new int MethodA() //隐藏该方法 { return 0; } }
6、调用函数的基类版本
语法:
base.<MethodName>()
调用基类中的任何方法。
7、抽象类和抽象函数
- 把类和函数声明为abstract。
- 抽象类不能实例化,抽象函数不能直接实现。
- 一个类包含了抽象函数,则该类必须声明为抽象的。
8、密封类和密封方法
- 把类和方法声明为sealed。
- 对于类,表示不能继承该类;对于方法,表示不能重写该方法。
9、构造函数的执行顺序
- 构造函数先调用System.Object的构造函数,
- 再按照继承的层次结构从上往下进行,直到最终要实例化的类为止,
- 说明:最先调用的是基类的构造函数,但如果类有静态构造函数,且为首次调用该类,则先调用的是子类的静态构造函数,再是父类的静态构造函数,当然静态构造函数只会执行这一次。
10、带参数的构造函数
- 在不考虑静态构造函数的情况下(因为静态构造仅执行一次,且定义静态构造函数的时候并不多)
- 子类在调用父类的构造函数时,默认情况是调用父类的无参构造函数,
- 如果父类只有带参构造函数,而没有无参构造函数,那么编译时会报错;不过我们可以通过base关键字来指定调用带参构造函数。
//父类 public class SuperClass { public SuperClass(string param) { Console.WriteLine("Super:" + param); } } //子类 public class ChildClass : SuperClass { public ChildClass(string param):base(param) { Console.WriteLine("Child:" + param); } }
11、接口的定义
- 在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的实现方式。
- 一般情况下,接口只能包含方法、属性、索引器和事件的声明。
12、派生的接口
- 接口可以彼此继承,其方式与类的继承方式相同。
- 可以在派生接口中定义新的方法,
- 但是,实现派生自该派生接口的类必须实现派生接口和基类接口的所有方法。
13、修饰符的分类
1、可见性修饰符
修饰符 应用 说明 public 所有类型或成员 任何代码均可以访问 protected 类型和内嵌类型的所有成员 只有派生的类型可以访问 internal 所有类型或成员 只能在包含它的程序集中访问 private 类型和内嵌类型的所有成员 只能在它所属的类型中访问 protected internal 类型和内嵌类型的所有成员 只能在包含它的程序集和派生类型的任何代码中访问 2、其他修饰符
修饰符 应用 说明 new 函数成员 成员用相同的签名隐藏继承的成员 static 所有成员 成员不作用于类的具体实例 virtual 仅函数成员 成员可以由派生类重写 abstract 仅函数成员 虚拟成员定义了成员的签名,但没有提供实现代码 override 仅函数成员 成员重写了继承的虚拟或抽象成员 sealed 类、方法和属性 对于类,不能继承自密封类,对于属性和方法,任何派生类中的任何成员都不能重写该成员 extern 仅静态方法 成员在外部用另一种语言实现