派生クラスでメソッドがオーバーライドされないようにするにはどうすればよいですか?
Javaでは、オーバーライドされないようにするメソッドでfinal
修飾子を使用してこれを行うことができます。
C#で同じようにするにはどうすればよいですか?
私はsealed
の使用を認識していますが、どうやらoverride
キーワードでのみ使用できますか?
_class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
_
したがって、上記の例では、methodB()
がクラスB
から派生するクラスによってオーバーライドされるのを防ぐことができますが、クラスB
がmethodB()
そもそも?
更新:この質問を投稿したときに、クラスAのmethodB()
宣言でvirtual
キーワードを逃しました。修正しました。
何もする必要はありません。 virtual
修飾子は、メソッドをオーバーライドできることを指定します。省略すると、メソッドは「最終」になります。
具体的には、メソッドをオーバーライドするには、メソッドがvirtual
、abstract
、またはoverride
である必要があります。
new
キーワードを使用すると、基本クラスメソッドを非表示にすることができますが、それでもオーバーライドされません。つまり、A.methodB()
を呼び出すと、基本クラスバージョンが取得されますが、B.methodB()
新しいバージョンを取得します。
すでに述べたように、sealed
withoverride
を使用することで、クラスBのMethodBがさらにオーバーライドされるのを防ぐことができます。
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
sealed
修飾子の使用とともにoverride
は、派生クラスがメソッドをさらにオーバーライドすることを防ぎます。
クラスAのmethodB
を子クラスでオーバーライドしたくない場合は、そのメソッドにvirtual
をマークしないでください。単にそれを削除します。 virtualキーワードを使用すると、メソッドを子クラスでオーバーライドできます
public void methodA()
{
}
クラスでsealed
キーワードを使用して、クラスがさらにオーバーライドされないようにします
C#では、virtual
とマークされていない関数(仮想関数のオーバーライドも含まれます)は効果的にシールされ、オーバーライドできません。したがって、基本クラスに同じシグネチャでvirtualとマークされたメソッドがない限り、overrideキーワードは無効であるため、サンプルコードは実際にはコンパイルされません。
A.methodB()が仮想としてマークされている場合、Aからメソッドをオーバーライドできますが、表示されているとおりにsealed
キーワードを使用して、より間接的に派生するクラスでメソッドがオーバーライドされるのを防ぐことができます。
留意すべきことの1つは、メソッドのオーバーライドは防止できますが、メソッドhidingはできません。クラスAの現在の定義を考えると、クラスBの次の定義は正当であり、それに対して何も実行できません。
class B:A
{
public new void methodB()
{
//code
}
}
new
キーワードは、この1つのメソッドに関連するため、基本的に継承/オーバーライド階層を「破壊」します。クラスB(またはそれ以上の派生型)として扱われるクラスBへの参照は、クラスBの実装を使用し、Bの実装が明確にコールバックしない限り、クラスAの実装を無視します。ただし、クラスBのインスタンスを(キャストするか、パラメーターとして渡すことにより)クラスAとして扱う場合、「新しい」実装は無視されます。
これは、クラスAとして扱われ、仮想methodBを本当にオーバーライドするクラスBが、クラスBのメソッドのオーバーライドを引き続き使用するオーバーライドとは異なります。また、メソッドの非表示が推測されることも理解してください(ただし、コンパイラの警告が表示されます)。派生クラスで同じシグネチャを持つメソッドを宣言し、newまたはoverrideのいずれも指定しない場合、基本クラスメソッドは非表示になります。
基本クラスでは、sealedキーワードはクラスの派生を防ぐためにのみ使用されますが、継承されたクラスでは、別の継承されたクラスがメソッドをオーバーライドするのを防ぐために使用できます。
基本クラスメソッドがオーバーライドされないようにするには、それを仮想として指定しないでください。提供した例では、元のクラスでmethodB
が仮想としてマークされていないため、クラスBはmethodB
をオーバーライドできませんでした。
これはコンパイルされます:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
これはしません:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
編集済み:封印されたキーワードに関する私の元のステートメントを明確にし、修正しました