Posso impedire che un metodo virtuale ereditato venga sovrascritto nelle sottoclassi?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Ho alcune lezioni strutturate in questo modo

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
    }
}

È possibile impedire alla classe C di sovrascrivere il metodo Render, senza interrompere il codice seguente?

A obj = new C();
obj.Render();       // calls B.Render -> c.SpecialRender
È stato utile?

Soluzione

Puoi sigillare i singoli metodi per evitare che vengano sovrascritti:

public sealed override void Render()
{
    // Prepare the object for rendering        
    SpecialRender();
    // Do some cleanup    
}

Altri suggerimenti

Sì, puoi utilizzare la parola chiave seal nell'implementazione di Render della classe B:

class B : A
{
    public sealed override void Render()
    {
        // Prepare the object for rendering
        SpecialRender();
        // Do some cleanup
    }

    protected virtual void SpecialRender()
    {
    }
}

In B, fallo

protected override sealed void Render() { ... }

Tentativo sealed

class B : A
{
  protected sealed override void SpecialRender()
  {
    // do stuff
  }
}

class C : B
  protected override void SpecialRender()
  {
    // not valid
  }
}

Naturalmente, penso che C possa aggirare il problema essendo new.

SÌ.Se contrassegni un metodo come Sealed, non sarà possibile sovrascriverlo in una classe derivata.

Un altro modo (migliore?) è probabilmente quello di utilizzare la parola chiave new per impedire che un particolare metodo virtuale venga sovrascritto:

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 
    //{
    //}
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top