ポリモーフィックなメソッド
C#はポリモーフィックなメソッドに関して、Javaに比べて少し複雑になっている。
using System; class Base { public void Method() { Console.WriteLine("base class"); } } class Sub : Base { public void Method() { Console.WriteLine("sub class"); } } class Program { static void BaseMethod(Base b) { b.Method(); } static void SubMethod(Sub s) { s.Method(); } static void Main(string[] args) { BaseMethod(new Base()); SubMethod(new Sub()); BaseMethod(new Sub()); } }
これの実行結果は、
base class
sub class
base class
となる。メソッドをオーバーライドしたい場合、スーパークラスのメソッドにvirtualを、サブクラスのメソッドにoverrideを指定する必要がある。
virtualなし | virtualあり | |
---|---|---|
overrideあり | コンパイルエラー | オーバーライド |
overrideなし | 隠蔽 | 隠蔽 |
隠蔽はnewキーワードを使って明示的にやれとの警告が出る。
あと、クラス階層が3階層以上の場合、上の階層でvirtualが指定されていればそれより下の階層は全部overrideとしていする*1。
例えば、
class SubSub : Sub { public override void Method() { Console.WriteLine("sub sub class"); } }
これを追加すれば、BaseMethod(new SubSub())とやってもSubMethod(new SubSub())とやってもsub sub classと表示される。
base class
sub class
sub class
sub sub class
sub sub class
ここら辺の明示的に指定する方法、昔は嫌いだったんだけど、間違いを見つけやすくする、って言う点で今はかなり好きだ。いっそ、newキーワードを使わずに隠蔽もエラーにしてしまってもいいくらい。ビバ冗長。
追記:
virtualとoverrideとかnewとoverrideは同居出来ないけど、newとvirtualは同居可能。
例えば、上のプログラムのSubクラスを
class Sub : Base { public new virtual void Method() { Console.WriteLine("sub class"); } }
に変更すると、
base class
sub class
base class
base class
sub sub class
となる。
*1:virtualとoverrideは同時に指定出来ない