【问题标题】:Why abstract class cannot have Sealed method [duplicate]为什么抽象类不能有密封方法[重复]
【发布时间】:2018-06-19 06:14:31
【问题描述】:

代码片段 1(编译错误)- A.M2() 不能被密封,因为它不是覆盖

abstract class A
{
    public abstract void M1();

    public sealed void M2()
    {
        // Do Something
    }
}

代码片段 2(工作正常)

abstract class A
{
    public abstract void M1();

    public virtual void M2()
    {

    }
}

class B : A
{
    public sealed override void M1()
    {

    }

    public sealed override void M2()
    {

    }
}

问题 - 如果我在 Abstract class 本身中提供方法的实现,为什么 C# 不允许我标记它Sealed,为什么它要我在子类中覆盖,然后标记它作为密封。我无法理解这种差异

【问题讨论】:

  • 方法默认是sealed,如果它们没有被声明为虚拟并且没有覆盖另一个虚拟方法。因此,如果您在基类本身中提供实现,并且您不希望派生类覆盖该方法,则不必将它们标记为virtual,仅此而已。
  • This 可能会让事情变得清晰
  • @sthotakura 方法默认是不密封的,因为新的实现可以在子类中,它隐藏了旧的,没有任何编译错误
  • @MrinalKamboj 隐藏具有new 实现的方法与override 实现不同。除非在基类中将其标记为 virtual,否则您无法覆盖该方法。
  • 什么意思?当然,您可以将抽象类中的方法标记为密封的。像这样:public abstract class Z { public virtual void M() { } } public abstract class A : Z { public sealed override void M() { } }

标签: c# oop abstract-class sealed


【解决方案1】:

Sealed 关键字只能放在可覆盖的函数上。 您指定的该函数未声明为虚拟函数,因此不可覆盖。此外,将函数声明为“虚拟”和“密封”也没有任何意义,因为密封取消了“虚拟”

Sealed only 可以与“override”关键字一起使用,并阻止其他类覆盖函数本身。

【讨论】:

  • 我的问题不是“如何”/“什么”,从代码中可以清楚地知道可以做什么,但是“为什么”抽象类限制密封方法,理想情况下它不是设计问题和实现已经在抽象类中可用
  • 但是已经被限制为不指定为虚函数了。
  • 如果函数还不是虚函数,则不能将其标记为“密封”
  • 我想了解的是,如果他们允许密封非虚拟方法,则复杂性/问题。在任何情况下,非虚方法都可以隐藏在子类中,并且只有警告
  • “为什么”的答案就是 C# 的设计/构建方式。
【解决方案2】:

它与abstract 类无关。除非它是派生类中的重写方法,否则您不能在任何类中将方法设为密封。

如果您打算限制它在派生类中被覆盖,那么您最好使用private 访问修饰符。

以及你可以在派生类中使用sealed的原因;我在下面有一个例子

您有三个类A,B,C,其中B 覆盖AC 派生自B -> B:A, C:B

 abstract class A
    {
        public abstract void MyMethod();
    }

    class B : A
    {
        public sealed override void MyMethod()
        {

        }
    }

    class C : B
    {
        public override void MyMethod()
        {

        }
    }

在上面的例子中,我们可以覆盖B 类中A 的方法,因为它不是密封的。但是如果你在C类中重写B的方法,那么由于sealed关键字是不允许的。

它将限制对B 类的进一步覆盖。那就是我们可以使用sealed

【讨论】:

    猜你喜欢
    • 2014-01-24
    • 2019-07-14
    • 2013-10-24
    • 2016-02-13
    • 2012-11-29
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多