Puis-je empêcher qu’une méthode virtuelle héritée soit remplacée dans les sous-classes ?
-
09-06-2019 - |
Question
J'ai des cours organisés comme ceci
class A
{
public virtual void Render()
{
}
}
class B : A
{
public override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
class C : B
{
protected override void SpecialRender()
{
// Do some cool stuff
}
}
Est-il possible d'empêcher la classe C de remplacer la méthode Render, sans casser le code suivant ?
A obj = new C();
obj.Render(); // calls B.Render -> c.SpecialRender
La solution
Vous pouvez sceller des méthodes individuelles pour éviter qu'elles ne soient remplacées :
public sealed override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
Autres conseils
Oui, vous pouvez utiliser le mot-clé scellé dans l'implémentation de Render par la classe B :
class B : A
{
public sealed override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
En B, faites
protected override sealed void Render() { ... }
essayer sealed
class B : A
{
protected sealed override void SpecialRender()
{
// do stuff
}
}
class C : B
protected override void SpecialRender()
{
// not valid
}
}
Bien sûr, je pense que C peut contourner ce problème en étant new
.
Oui.Si vous marquez une méthode comme Sealed, elle ne peut pas être remplacée dans une classe dérivée.
Une autre (meilleure ?) méthode consiste probablement à utiliser le nouveau mot-clé pour empêcher qu'une méthode virtuelle particulière soit dépassée :
class A
{
public virtual void Render()
{
}
}
class B : A
{
public override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
class B2 : B
{
public new void Render()
{
}
}
class C : B2
{
protected override void SpecialRender()
{
}
//public override void Render() // compiler error
//{
//}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow