Java プログラマが C# を学ぶ際のメモ。final については探しても見当たらなかったので書いておきます。
定数・フィールドのfinal
定数に対しては const 識別子, コンストラクタ値を設定する書き込み禁止フィールドについては readonly 識別子を使います。
class Foo { private const int NUM_MAX = 65535; // 定数値。コンストラクタでの遅延代入が不可。 private readonly int _id; // 書き込み禁止値。コンストラクタで遅延代入が可能。 <pre><code>public Foo(int id){ _id = id; } </code></pre> }
メソッド中で、遅延代入をする方法はなさそうです。
public doSomething(){ readonly int j = 1; // これはエラー。readonly はフィールドでのみ可能。 const int N; N = 10; // これもエラー。const は宣言と同時に代入しなければならない。 }
同様に、引数の final (引数の変数への再代入禁止)を C# で利用することはできません。
public void doSomeThing2(const int number); // const は引数には適用不可
クラスのfinal
クラスに対しては、sealed 識別子が同等の効果をもちます。
sealed class FinalClass{ /* … */ }
メソッドのfinal
Java におけるメソッドの宣言に対しての final は、C# ではデフォルトの実装のため、ポリモーフィズムについては C# のほうが Java より制限的といえます。
final でない(オーバーライド可能な)メソッドを定義するには、親で virtual 識別子をつけて宣言し、かつ子で override 識別子で明示してオーバーライドします。
override 識別子をつけている場合、さらにその子クラスでも再帰的にオーバーライドが可能です。オーバーライド可能なメソッドに対して「オーバーライドした上で子には禁止する」という動作を実装する場合は、クラスと同様に sealed 識別子を利用します。
class Parent { public virtual void Greet(){ // オーバーライド可能 Console.WriteLine(“Hello”); } public void StandUp(){ // オーバーライド禁止。オーバーライドしようとするとコンパイルエラー // … } } class Child : Parent { public override void Greet(){ // オーバーライド。明示しないとコンパイルエラー Console.WriteLine(“Hi!!”); } } class GrandChild : Child { public sealed override void Greet(){ // オーバーライド。ただし、このクラスの子にはオーバーライドを許さない。 } }
参考:
-
C# のキーワード(MSDN)
-
C# で Java の final の 1機能を使いたい(@IT Java Solution Forum)