|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:' i7 y2 x. i; q4 V% P/ p9 c1 l
/ I+ x6 C3 k7 h- D6 K
class BaseClass {$ I; `0 P- B( t- b3 S
public void SimpleMethod() {
1 [* q1 ^4 m$ a! t DebugMgr.start( 10, "BaseClass.SimpleMethod");( W0 P. i9 V4 O0 \% c; @5 R& p
DebugMgr.end( 10);; q* T- r) i& a+ i8 I! W1 }. u" G
class Subclassed : BaseClass {5 Q0 M, H9 e, |( {4 f
public new void SimpleMethod() {
% Q% i; I9 [) m2 C5 e$ C DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);
, f! w: M6 \6 j3 o8 S. X7 a; R: c- }( b& i
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。
4 |/ R% q' J9 [/ p8 R
# m6 g) y) z9 g! ? 当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。9 F1 B( L7 E; S; v& u) l) `& H, S
$ }8 N6 `' W9 h
下面的代码说明如何使用定义的类型:
: F( M7 a/ p, z+ W0 n
, G; K' Y* {& z8 @! o1 } Subclassed subcls = new Subclassed(); subcls.SimpleMethod();4 R$ q' O6 ^1 z6 `
DebugMgr.output( 10, "Now assigning to type BaseClass");
/ d; r: _. H7 [* A: [- P# K BaseClass basecls = subcls; basecls.SimpleMethod();0 {( P: j4 |8 x, Z: H
?! A0 P \8 u" f4 w Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:
0 w& u0 B3 O0 i8 j) A* C8 f6 |' F* W" }3 c9 f/ G
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)
& u }/ J4 j7 @
6 s( }' q/ W/ b4 \* Q% d3 H 当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。6 x+ V! e* P; E* C
|
|