Puis-je empêcher qu’une méthode virtuelle héritée soit remplacée dans les sous-classes ?

StackOverflow https://stackoverflow.com/questions/43511

  •  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
Était-ce utile?

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
scroll top