|
|
最简单的继承就是一个类型定义了一个方法,它的子类又重新定义了该方法。见下面的例子:
: U0 f k1 S' o* U" c P# S
8 z. Q8 E0 C- B$ }6 Y( W- ] class BaseClass {
0 }4 W3 c0 R& ~1 h public void SimpleMethod() {6 R0 z- l2 e# P
DebugMgr.start( 10, "BaseClass.SimpleMethod");
; S3 P! ]0 s+ K. m DebugMgr.end( 10);6 G/ _$ A, y* c2 _ h, p
class Subclassed : BaseClass {
8 F- Q- H9 a: F- x+ ~! y public new void SimpleMethod() {1 k/ O( U$ `2 }0 \* k7 h
DebugMgr.start( 10, "Subclassed.SimpleMethod"); DebugMgr.end( 10);/ N, }% B6 Y& @
4 I7 S$ F! D* ^; b( \
BaseClass类定义了S彳mpleMethod方法,Subclassed类是BaseClass类的子类,它重新定义了SimpleMethod方法。注意关键字new的使用,正是关键字new使C#和其他.NET语言成为具有一致继承管理能力的软件开发语言。
- F1 W% Z9 j+ ?" W( W% o* J1 R2 e& Z: H+ |5 P+ D1 ^
当一个类继承自另一个类,并定义了一个和父类中相同的方法后,这个类就覆盖(over-ride) 了这个方法。覆盖意味着用一个新的功能来代替旧的功能。新功能的代码可能会引入新的问题。要避免这样的问题,C#和.NET要求开发人员在覆盖一个方法时给出明确的说明。以此提醒开发人员该功能在基类中有不同的实现。3 ]! M4 f8 H) {% _4 f5 V
# Y" c: w) x$ T! B- Q- O6 q4 d 下面的代码说明如何使用定义的类型:. Y8 p8 k8 ~4 Y/ N0 k' b+ G7 E
4 K, E" g4 Q5 o! r( v9 u; G Subclassed subcls = new Subclassed(); subcls.SimpleMethod();
) ^. L, E$ y7 @9 x DebugMgr.output( 10, "Now assigning to type BaseClass");
! J' [& e {0 o BaseClass basecls = subcls; basecls.SimpleMethod();4 B" h: L0 s" t
# [. {- H( w) U C* ^; g* Y7 L
Subclassed类型被实例化,并被赋值给同样声明为Subclassed类型的变量subcls。接下来,调用SecondMethod方法,然后将实例向上转型为父类BaseClass类型,并赋值给basecls变量,并再一次调用了 S1mpleMethod方法。下面是这个示例代码执行后产生的输出信息:
4 d: W: r% ^6 C# g: Z7 P) m) N6 X
start (Subclassed.SimpleMethod) end (Subclassed.SimpleMethod) Now assigning to type BaseClass start (BaseClass.SimpleMethod) end (BaseClass.SimpleMethod)
6 ^8 \5 i0 t5 _+ [: `$ w$ P& o$ T! ]8 f8 e! S3 n
当使用了关键字new,使用者使用的功能要取决于类型和类型转换。假设实例化了BaseClass类型,如果该实例向下转型为Subclassed,则会调用Subclassed的方法,因为Subclassed拥有SecondMethod方法的实现。如果将实例的类型转换回BaseClass,由于BaseClass自己也实现SecondMethod方法,所以将会调用BaseClass的方法。这是个很清晰的继承模型,因为所执行的方法的实现都是基于类型的转换。
* m( ?3 j, [! c, l% {7 t3 O |
|