虚拟、覆盖、新建和密封覆盖之间的区别

2024-01-07

我对 OOP 的一些概念很困惑:virtual, override, new and sealed override。谁能解释一下这些差异吗?

我很清楚,如果要使用派生类方法,可以使用override关键字使得基类方法将被派生类覆盖。但我不确定new, and sealed override.


The virtual关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中重写它。例如,任何继承它的类都可以重写此方法: 使用 new 修饰符显式隐藏从基类继承的成员。要隐藏继承的成员,请在派生类中使用相同的名称声明它,并使用 new 修饰符对其进行修改。

这都与多态性有关。当对引用调用虚拟方法时,引用所引用的对象的实际类型用于决定使用哪个方法实现。当在派生类中重写基类的方法时,即使调用代码不“知道”该对象是派​​生类的实例,也会使用派生类中的版本。例如:

public class Base {
    public virtual void SomeMethod() {
    }
}

public class Derived : Base {
    public override void SomeMethod() {
    }
}

...

Base d = new Derived();
d.SomeMethod();

如果覆盖 Base.SomeMethod,最终将调用 Derived.SomeMethod。

现在,如果您使用new关键字而不是override,派生类中的方法不会覆盖基类中的方法,它只是隐藏它。在这种情况下,代码如下:

public class Base {
    public virtual void SomeOtherMethod() {
    }
}

public class Derived : Base {
    public new void SomeOtherMethod() {
    }
}

...


Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();

将首先调用 Base.SomeOtherMethod ,然后调用 Derived.SomeOtherMethod 。它们实际上是两个完全独立的方法,恰好具有相同的名称,而不是派生方法重写基本方法。

如果您不指定 new 或 overrides,则结果输出与指定 new 相同,但您还会收到编译器警告(因为您可能不知道您在基类中隐藏了方法)方法,或者实际上您可能想覆盖它,只是忘记包含关键字)。

压倒一切的属性声明可能包括sealed修饰符。使用此修饰符可防止派生类进一步重写该属性。密封属性的访问器也被密封。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

虚拟、覆盖、新建和密封覆盖之间的区别 的相关文章

随机推荐