|
|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:
% H- f( ]: |8 N. q
% m6 c1 c, t# x5 n2 s4 Y class BaseClass {
* z4 @+ c5 w/ w* f- l& Y public void SimpleMethod() {8 K0 n( Q9 @; ^' R
DebugMgr.start( 10, "BaseClass.SimpleMethod");& q0 ~& y/ M0 H) \- Y! k0 e. v
DebugMgr.end( 10);
- M% z* Z8 ]9 k( y$ B class Subclassed : BaseClass {
3 e7 I4 i, m; M* B( |3 D9 U public new void SimpleMethod() {
3 j6 e5 X3 |( F. ^2 _: H. u DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);
0 x' X& ` Z+ ~2 _* v- L- T2 A6 K- D
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。' q/ R4 s% \% u M% v) _) e
7 X3 w; U; J) _1 I+ n4 ] 当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。
( `$ j+ E5 e5 ], c' Q
% L; _' U8 E0 ]; i; t6 j 下面的代码说明如何使用定义的类型:
( t; i: z, m3 l8 B; H; I/ F1 G- _8 l. M% U- n7 Z( Z( z" D+ V
Subclassed subcls = new Subclassed(); subcls.SimpleMethod();: C) u p% K( x
DebugMgr.output( 10, "Now assigning to type BaseClass");7 D% r* b- e1 [2 V, Q0 ~( Y+ F
BaseClass basecls = subcls; basecls.SimpleMethod();+ ^4 ]7 k# s* i! @
7 F3 I$ X0 X" x: p3 S. L
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:7 w% A$ F4 B6 M( L, J1 o
! V4 M0 \- @/ @3 }& |
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)9 ?) D. j+ [0 Y3 m# F
3 x& l# G* e1 X: _- |9 ~ 当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。! r4 V' C5 B0 O0 y) K5 t. I9 V
|
|