Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么抽象类不能有密封方法_C#_Oop_Abstract Class_Sealed - Fatal编程技术网

C# 为什么抽象类不能有密封方法

C# 为什么抽象类不能有密封方法,c#,oop,abstract-class,sealed,C#,Oop,Abstract Class,Sealed,代码段1(编译错误)-A.M2()无法密封,因为它不是重写 代码片段2(工作正常) 问题-如果我在抽象类本身中提供方法的实现,为什么C#不允许我将其标记为Sealed,为什么它希望我在子类中重写,然后将其标记为Sealed。我无法理解这种差异Sealed关键字只能放在可重写的函数上。 您指定的函数未声明为虚拟函数,因此不可重写。此外,将函数声明为“虚拟”和“密封”也没有任何意义,因为密封抵消了“虚拟” Sealed only可以与“override”关键字一起使用,并阻止其他类重写函数本身。Se

代码段1(编译错误)-A.M2()无法密封,因为它不是重写

代码片段2(工作正常)


问题-如果我在
抽象类
本身中提供方法的实现,为什么C#不允许我将其标记为
Sealed
,为什么它希望我在子类中重写,然后将其标记为Sealed。我无法理解这种差异

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


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

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


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

它与
抽象类无关。除非方法是派生类中的重写方法,否则不能使其在任何类中密封

若您打算限制它在派生类中的重写,那个么最好使用
private
access修饰符

以及为什么可以在派生类中使用sealed;下面我举了一个例子

您有三个类
A、B、C
,其中
B
覆盖
A
C
派生自
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
的方法,则由于关键字已密封,因此不允许使用该方法


它将限制类
B
的进一步覆盖。这就是我们可以使用
密封的

它与
抽象类无关。除非方法是派生类中的重写方法,否则不能使其在任何类中密封

若您打算限制它在派生类中的重写,那个么最好使用
private
access修饰符

以及为什么可以在派生类中使用sealed;下面我举了一个例子

您有三个类
A、B、C
,其中
B
覆盖
A
C
派生自
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
的方法,则由于关键字已密封,因此不允许使用该方法


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

方法的地方。默认情况下,如果这些方法未声明为virtual并且未重写另一个virtual方法,那么它们是
sealed
。因此,如果您在基类本身中提供一个实现,并且不希望派生类重写该方法,那么您不必将它们标记为虚拟的,仅此而已。可能会制造一些东西clear@sthotakura默认情况下,方法不是密封的,因为新的实现可以位于子类中,而子类隐藏旧的实现,而无需任何编译error@MrinalKamboj使用
new
实现隐藏方法与
override
隐藏实现不同。除非方法在基类中标记为
virtual
,否则无法重写该方法。这是什么意思?当然,您可以将抽象类中的方法标记为sealed。如下所示:
public abstract class Z{public virtual void M(){}}public abstract class A:Z{public sealed override void M(){}
方法在默认情况下是
sealed
,如果它们没有声明为virtual并且没有重写另一个虚拟方法的话。因此,如果您在基类本身中提供一个实现,并且不希望派生类重写该方法,那么您不必将它们标记为虚拟的,仅此而已。可能会制造一些东西clear@sthotakura默认情况下,方法不是密封的,因为新的实现可以位于子类中,而子类隐藏旧的实现,而无需任何编译error@MrinalKamboj使用
new
实现隐藏方法与
override
隐藏实现不同。除非方法在基类中标记为
virtual
,否则无法重写该方法。这是什么意思?当然,您可以将抽象类中的方法标记为sealed。像这样:
public abstract class Z{public virtual void M(){}}}public abstract class A:Z{public sealed override void M(){}}
我的问题不是“如何”/“什么”,从代码上看它清楚可以做什么,而是“为什么”抽象类限制sealed方法,理想情况下,它不是一个设计问题,抽象类中已经有了实现,但由于没有指定为虚拟函数,它已经受到限制。不能将函数标记为“密封”如果它还不是一个虚拟函数,我试图理解的是,如果它们允许密封非虚拟方法,那么它的复杂性/问题。在任何情况下,非虚拟方法都可以隐藏在子类中,只有警告您“为什么”的答案就是C#是如何设计/构建的。我的问题不是“如何”/“什么”,从代码中可以清楚地看出可以做什么,而是“为什么”抽象类限制了密封方法,理想情况下,它不是一个设计问题,抽象类中已经有了实现,但由于没有指定为虚拟函数,它已经受到限制。如果函数不是虚拟函数,则不能将其标记为“密封”
 abstract class A
    {
        public abstract void MyMethod();
    }

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

        }
    }

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

        }
    }