这一课讲述怎样在C#中使用override和new这两个关键字。在C#手册中把他们统称为
versioning.(chsarp园地注:不知道应该怎样翻译才确切,敬请指正!)。它维持了基 &E_0W+x(n&c1u$i
类和派生类之间的进化关系。
C#语言设计这种机制的目的是为了能够保持不同库的基类和派生类之间的关系,以及
向后兼容性。例如,在派生类中引入一个基类的同名成员并不是错误的。但是要求必 7N]7U c6V+X
须显示的声明一个方法是重载一个继承的方法,还是简单的指定了一个新的方法。 8LsL xG {+?P-v H
C#中方法缺省不是virtual的。必须在基类中显示指明。这样在派生类中,就可以用 1mz%fzx df8F
override重载基类方法,或者用new隐藏虚拟方法。如果两个关键子都没有使用,编 ![$hchFsw:ot
译器会对派生类中的同名方法发出警告。下面举例: mEz.oSyH3z
例子 )z!rm i2G,nU |
000: // Versioning/versioning.cs
001: public class MyBase ;l3ql?em@v f'K
002: { .D;v0V%ThT(S~ K
003: public virtual string Meth1()
004: {
005: return "MyBase-Meth1";
006: } H3q6]5em
007: public virtual string Meth2() 4@}-d S^X lw}
008: { `C6pB5d'r
009: return "MyBase-Meth2"; 0ro(FW iw;c-ef*Y
010: }
011: public virtual string Meth3()
012: {
013: return "MyBase-Meth3"; p(r1a0AsfS@:t
014: }
015: }
016: ]Q+r w/
017: class MyDerived : MyBase
018: {
019: public override string Meth1()
020: {
021: return "MyDerived-Meth1";
022: }
023: public new string Meth2()
024: { 9j.U_0bY?
025: return "MyDerived-Meth2"; #{ Uy2eY1t,M b
026: } B|;Axefg
027: public string Meth3() // Issues a warning to alert the programmer
028: // that the method hides the inherited
029: // member MyBase.Meth3().
030: { %q/7ZM D/p@$M
031: return "MyDerived-Meth3";
032: } 1f!a^%p9I2g9S V
033:
034: public static void Main() guO},e5k@
035: { 5q az,Xc;P
036: MyDerived mD = new MyDerived(); 'v(y6Zhzj[
037: MyBase mB = (MyBase) mD; "x.m)Yq_8N J4R
038: JZk$| H@?S1G V
039: System.Console.WriteLine(mB.Meth1()); )w,U? EM5P7hQw;CN
040: System.Console.WriteLine(mB.Meth2()); 'FAMM*{@ R
041: System.Console.WriteLine(mB.Meth3()); ~;w _x"H(^+T
042: } ^'IyihiMQ~i;h
043: }
输出结果
MyDerived-Meth1 0z+/-A7D(NBK
MyBase-Meth2 kiIhO
MyBase-Meth3
[代码解释]
* 第19行用关键字override重载方法Meth1 )sz:j*]+Bp_0/7^ k6j
* 第23行用关键字new隐藏了方法Meth3
* 第27行隐藏了虚拟方法Meth3,因为没有使用任何关键字,这样编译器会对程序报警。 iP SIb:O ]
在派生类中隐藏基类成员在C#中不是错误。这种特性能够让基类在不破坏其它继承了它
的库的前提下发生改变。举个例子
class Base {} :~D#lQuzdV
class Derived: Base
{ J2@/S5_JJ_#U
public void F() {}
} +c$`n0N$Ha8B Wq
以后,基类也可以增加一个方法F() ,Z0LKO/$J8}
class Base oG%K(V/l5{!}
{
public void F() {}
}
class Derived: Base
{ vlQ8X$`%O
public void F() {}
} %Q;rY+NJ g8q6A
这样,基类和派生类就能够自由地保证二进制代码的兼容性了!
versioning.(chsarp园地注:不知道应该怎样翻译才确切,敬请指正!)。它维持了基 &E_0W+x(n&c1u$i
类和派生类之间的进化关系。
C#语言设计这种机制的目的是为了能够保持不同库的基类和派生类之间的关系,以及
向后兼容性。例如,在派生类中引入一个基类的同名成员并不是错误的。但是要求必 7N]7U c6V+X
须显示的声明一个方法是重载一个继承的方法,还是简单的指定了一个新的方法。 8LsL xG {+?P-v H
C#中方法缺省不是virtual的。必须在基类中显示指明。这样在派生类中,就可以用 1mz%fzx df8F
override重载基类方法,或者用new隐藏虚拟方法。如果两个关键子都没有使用,编 ![$hchFsw:ot
译器会对派生类中的同名方法发出警告。下面举例: mEz.oSyH3z
例子 )z!rm i2G,nU |
000: // Versioning/versioning.cs
001: public class MyBase ;l3ql?em@v f'K
002: { .D;v0V%ThT(S~ K
003: public virtual string Meth1()
004: {
005: return "MyBase-Meth1";
006: } H3q6]5em
007: public virtual string Meth2() 4@}-d S^X lw}
008: { `C6pB5d'r
009: return "MyBase-Meth2"; 0ro(FW iw;c-ef*Y
010: }
011: public virtual string Meth3()
012: {
013: return "MyBase-Meth3"; p(r1a0AsfS@:t
014: }
015: }
016: ]Q+r w/
017: class MyDerived : MyBase
018: {
019: public override string Meth1()
020: {
021: return "MyDerived-Meth1";
022: }
023: public new string Meth2()
024: { 9j.U_0bY?
025: return "MyDerived-Meth2"; #{ Uy2eY1t,M b
026: } B|;Axefg
027: public string Meth3() // Issues a warning to alert the programmer
028: // that the method hides the inherited
029: // member MyBase.Meth3().
030: { %q/7ZM D/p@$M
031: return "MyDerived-Meth3";
032: } 1f!a^%p9I2g9S V
033:
034: public static void Main() guO},e5k@
035: { 5q az,Xc;P
036: MyDerived mD = new MyDerived(); 'v(y6Zhzj[
037: MyBase mB = (MyBase) mD; "x.m)Yq_8N J4R
038: JZk$| H@?S1G V
039: System.Console.WriteLine(mB.Meth1()); )w,U? EM5P7hQw;CN
040: System.Console.WriteLine(mB.Meth2()); 'FAMM*{@ R
041: System.Console.WriteLine(mB.Meth3()); ~;w _x"H(^+T
042: } ^'IyihiMQ~i;h
043: }
输出结果
MyDerived-Meth1 0z+/-A7D(NBK
MyBase-Meth2 kiIhO
MyBase-Meth3
[代码解释]
* 第19行用关键字override重载方法Meth1 )sz:j*]+Bp_0/7^ k6j
* 第23行用关键字new隐藏了方法Meth3
* 第27行隐藏了虚拟方法Meth3,因为没有使用任何关键字,这样编译器会对程序报警。 iP SIb:O ]
在派生类中隐藏基类成员在C#中不是错误。这种特性能够让基类在不破坏其它继承了它
的库的前提下发生改变。举个例子
class Base {} :~D#lQuzdV
class Derived: Base
{ J2@/S5_JJ_#U
public void F() {}
} +c$`n0N$Ha8B Wq
以后,基类也可以增加一个方法F() ,Z0LKO/$J8}
class Base oG%K(V/l5{!}
{
public void F() {}
}
class Derived: Base
{ vlQ8X$`%O
public void F() {}
} %Q;rY+NJ g8q6A
这样,基类和派生类就能够自由地保证二进制代码的兼容性了!