|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:: T+ P. E8 s& |2 x
) [7 E% G6 ]) d. v9 E! b4 h+ p class BaseClass {
2 C& F; G8 a7 Q" r6 e( U$ R6 C public void SimpleMethod() {0 u1 G1 Y& @* p! T% c' V' [+ l
DebugMgr.start( 10, "BaseClass.SimpleMethod");
$ e- T- y3 y9 ^# C DebugMgr.end( 10);
7 c9 t! M2 c' g, ~+ d class Subclassed : BaseClass {
" q. `4 e( t2 n: G$ m7 b public new void SimpleMethod() {
4 { \( j) [- {, M, s DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);
# A' o, D9 h4 ?9 k4 |* M) q4 a- L$ V, s5 ~- s
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。
5 X3 J+ l8 ]7 y: t9 f! I6 a p8 } \. g1 \- ]1 `1 N+ Y7 Y0 J- k* Y
当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。* ^9 x% S! F% x4 T
( Q# I9 j: k* G 下面的代码说明如何使用定义的类型:
( z! _' _$ I8 s8 v9 n4 e' T, @ N2 A1 o7 N% Z
Subclassed subcls = new Subclassed(); subcls.SimpleMethod();- S" r4 T" U6 `& }
DebugMgr.output( 10, "Now assigning to type BaseClass");
! w- F' [& z8 _3 j) k BaseClass basecls = subcls; basecls.SimpleMethod();
1 j# e- m$ _& s; M" M( X- C( a5 ]+ B, C8 q
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:: P2 o* C' v* u% {2 M& C! l2 s; Q- F
; F( e# N. q/ h" d5 K' |9 Q+ ?
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)
: z; Q/ L6 F( R; x0 d
5 x% O% E3 M2 X* K' w L# Q 当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。
& Y, F1 V5 k7 w9 v' v! B9 w |
|