【问题标题】:Can I prevent an inherited virtual method from being overridden in subclasses?我可以防止继承的虚方法在子类中被覆盖吗?
【发布时间】:2010-09-07 19:05:14
【问题描述】:

我有一些这样布置的课程

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

是否可以在不破坏以下代码的情况下防止C类覆盖Render方法?

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

【问题讨论】:

    标签: c# polymorphism


    【解决方案1】:

    另一种(更好的?)方法可能是使用 new 关键字来防止特定的虚拟方法被覆盖:

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

    【讨论】:

    • 任何解释为什么这样更好?密封有一个相当干净的意思。它说“经过一番思考后,我得出结论,这永远不应该被覆盖”。
    【解决方案2】:

    试试sealed

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

    当然,我认为 C 可以通过 new 来解决这个问题。

    【讨论】:

      【解决方案3】:

      是的,你可以在B类的Render实现中使用sealed关键字:

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

      【讨论】:

        【解决方案4】:

        是的。如果将方法标记为 Sealed,则不能在派生类中覆盖它。

        【讨论】:

          【解决方案5】:

          在B中,做

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

          【讨论】:

            【解决方案6】:

            您可以密封各个方法以防止它们被覆盖:

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

            【讨论】:

              猜你喜欢
              • 2015-07-09
              • 1970-01-01
              • 2015-10-04
              • 2012-02-05
              • 1970-01-01
              • 2015-10-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多