Kann ich verhindern, dass eine geerbte virtuelle Methode in Unterklassen überschrieben wird?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich habe einige Klassen, die so aufgebaut sind

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

Ist es möglich, zu verhindern, dass die C-Klasse die Render-Methode überschreibt, ohne den folgenden Code zu beschädigen?

A obj = new C();
obj.Render();       // calls B.Render -> c.SpecialRender
War es hilfreich?

Lösung

Sie können einzelne Methoden versiegeln, um zu verhindern, dass sie überschreibbar sind:

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

Andere Tipps

Ja, Sie können das Schlüsselwort „sealed“ in der Render-Implementierung der B-Klasse verwenden:

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

    protected virtual void SpecialRender()
    {
    }
}

In B tun Sie es

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

versuchen sealed

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

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

Natürlich denke ich, dass C das umgehen kann, indem er ist new.

Ja.Wenn Sie eine Methode als versiegelt markieren, kann sie in einer abgeleiteten Klasse nicht überschrieben werden.

Eine andere (bessere?) Möglichkeit besteht wahrscheinlich darin, das Schlüsselwort new zu verwenden, um zu verhindern, dass eine bestimmte virtuelle Methode überschrieben wird:

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 
    //{
    //}
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top