|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:
$ j/ k. S$ t3 l% a
) e* f) J7 b: j3 o8 v% T class BaseClass {
$ j9 s3 y# J, o1 f public void SimpleMethod() {4 |2 O% p4 p9 B* I+ f. q) v
DebugMgr.start( 10, "BaseClass.SimpleMethod");
1 i; g& Y( ` R- t9 G5 ]: z! _ DebugMgr.end( 10);( U9 f, {' V+ o" k
class Subclassed : BaseClass {8 e7 S7 i& S4 q6 {6 k0 A5 L
public new void SimpleMethod() {
2 I& U$ |/ t$ ~ DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);, O" m# n. x2 _& u6 f& }
# j* [- x' B* O
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。
' O1 \3 b$ w) Y1 D, s) E: \& P7 ^, Z. I( x6 ^ G3 k
当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。! ~: Z, ], G- `8 ~. M2 b. w* o
1 y) \% x. d! V3 I* l
下面的代码说明如何使用定义的类型:0 u6 h. ?* I7 Z% m! O
' [% U) j& d; Q5 W4 g+ ~
Subclassed subcls = new Subclassed(); subcls.SimpleMethod();. Q2 r! |1 }2 x: _+ D
DebugMgr.output( 10, "Now assigning to type BaseClass");" N3 O% ~0 s: X; @( T3 |
BaseClass basecls = subcls; basecls.SimpleMethod();
) x1 u; h* k, l* @' A9 O; k) ~6 p; Y0 w+ g* d3 J; G
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:, t. z! K$ t7 ?( p) Q! c& o/ D
/ Z% ^" k' I8 P" o8 q/ N
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)' ?5 o+ n! H B, h+ m& g
; i8 i/ {& n- j) T& d# i
当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。
" [0 W* C" c1 b: ^. y+ f3 X |
|