|
|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:
& W4 I! e k0 E+ _/ u8 T/ G' A) a! r6 J' p
class BaseClass {) v* c" f; D3 J% g# k
public void SimpleMethod() {! _8 j( }4 d; G3 O% S) D5 H' C
DebugMgr.start( 10, "BaseClass.SimpleMethod"); A: z% K+ K2 ?8 B' }2 d" h. E+ S
DebugMgr.end( 10);
# X {! X( V1 x. a6 u# O! L class Subclassed : BaseClass {
# F- b4 y; K9 F+ H3 x5 } public new void SimpleMethod() {2 m9 @! C0 @6 v" U" B
DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);
% \7 E2 s/ v6 o6 K3 K: z; P. y* ]6 @4 U
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。
. L- V! i8 N, _" A- t5 t3 t9 L# k
当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。( ^! N- U& o' t, Q' [- W6 M4 _/ |
/ }6 N: @/ v5 h7 n 下面的代码说明如何使用定义的类型:! } h7 U1 Q! Y$ d$ n
4 g+ d0 r# p4 i7 l2 m- b% O Subclassed subcls = new Subclassed(); subcls.SimpleMethod();! d/ I5 b0 {3 b' r
DebugMgr.output( 10, "Now assigning to type BaseClass");
: V" Y( u3 v" _ BaseClass basecls = subcls; basecls.SimpleMethod();
4 |: o1 l4 X% m9 R1 l' {0 \+ Y- ~7 w' Q& v- D6 C+ `2 G8 T
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:
* U. x) G' {0 `8 \
|2 r8 d1 b! ]9 _/ R5 h start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)
* F9 S( U6 J! O; V
9 P. [9 p1 G) ?7 Y$ h& J 当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。! D8 m$ N9 |# f* _
|
|