|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:
4 B v( c6 A& b, l$ o
& G' k' F8 F! u' V$ a. \ class BaseClass {# y! O' c9 i, I& [# a: Q
public void SimpleMethod() {
$ O* {0 S D1 Q+ [6 q DebugMgr.start( 10, "BaseClass.SimpleMethod");
/ ?4 A9 V" p+ l9 y DebugMgr.end( 10);& E' m. F. T n% N3 h3 y
class Subclassed : BaseClass {
4 v! D, ?/ Z0 v6 M+ [ public new void SimpleMethod() {2 S# h0 R8 G9 X4 A
DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);! |9 [! j2 W! X+ i$ j/ T) ]+ ~
+ k* M& i1 o" [- [( d2 p
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。5 y' c9 a/ A5 E/ c9 h+ O
. d' j1 r6 Y y5 U
当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。. N, _9 l6 k, s
2 j" C" J" v$ _7 S' V 下面的代码说明如何使用定义的类型:0 p* J1 W" q6 w4 a2 X; a
* Z8 a) d0 F, i6 C7 @8 c
Subclassed subcls = new Subclassed(); subcls.SimpleMethod();$ z7 ~/ b' W$ Y6 W5 \
DebugMgr.output( 10, "Now assigning to type BaseClass");
8 }& O% N' w) B BaseClass basecls = subcls; basecls.SimpleMethod();% p; H2 ~! p, s' t9 e7 }
8 V r1 l% Y2 h$ ?+ |
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:
5 w; L7 l3 {' {1 D1 ^2 c3 H6 I5 i; s8 r* T! e' L) @0 L8 x5 S
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)" T1 P, g& ~+ s( a( J1 y( b7 R7 K
( G' R- l6 B( N6 V: h) w 当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。) y) I0 X5 c5 e( U) p# t* H
|
|