在基本类型“virtual”中声明一个方法,然后在子类型中使用“override”关键字重写它,与在子类型中声明匹配的方法时简单地使用“new”关键字相比,两者之间有什么区别?
当前回答
Virtual / override告诉编译器这两个方法是相关的,在某些情况下,当你认为你在调用第一个(虚拟)方法时,实际上应该调用第二个(被重写)方法。这是多态性的基础。
(new SubClass() as BaseClass).VirtualFoo()
将调用子类的重载VirtualFoo()方法。
New告诉编译器,您正在向派生类添加与基类中的方法同名的方法,但它们之间没有关系。
(new SubClass() as BaseClass).NewBar()
将调用BaseClass的NewBar()方法,而:
(new SubClass()).NewBar()
将调用子类的NewBar()方法。
其他回答
Virtual / override告诉编译器这两个方法是相关的,在某些情况下,当你认为你在调用第一个(虚拟)方法时,实际上应该调用第二个(被重写)方法。这是多态性的基础。
(new SubClass() as BaseClass).VirtualFoo()
将调用子类的重载VirtualFoo()方法。
New告诉编译器,您正在向派生类添加与基类中的方法同名的方法,但它们之间没有关系。
(new SubClass() as BaseClass).NewBar()
将调用BaseClass的NewBar()方法,而:
(new SubClass()).NewBar()
将调用子类的NewBar()方法。
new关键字用于隐藏。-意味着你在运行时隐藏你的方法。输出将基于基类方法。 Override用于重写。-表示您正在调用派生类方法引用基类。输出将基于派生类方法。
我的解释来自于使用属性来帮助理解差异。
重写很简单,对吧?底层类型覆盖父类型。
新可能是误导(对我来说是)。使用属性更容易理解:
public class Foo
{
public bool GetSomething => false;
}
public class Bar : Foo
{
public new bool GetSomething => true;
}
public static void Main(string[] args)
{
Foo foo = new Bar();
Console.WriteLine(foo.GetSomething);
Bar bar = new Bar();
Console.WriteLine(bar.GetSomething);
}
使用调试器,你可以注意到Foo Foo有两个GetSomething属性,因为它实际上有两个版本的属性,Foo's和Bar's,为了知道使用哪个,c#“选择”当前类型的属性。
如果你想使用Bar的版本,你应该使用override或使用Foo Foo代替。
Bar Bar只有1,因为它想要GetSomething的全新行为。
我总是觉得这样的事情用图片更容易理解:
再一次,用joseph daigle的密码,
public class Foo
{
public /*virtual*/ bool DoSomething() { return false; }
}
public class Bar : Foo
{
public /*override or new*/ bool DoSomething() { return true; }
}
如果你像这样调用代码:
Foo a = new Bar();
a.DoSomething();
注意:重要的是,我们的对象实际上是一个Bar,但我们将它存储在类型为Foo的变量中(这类似于强制转换它)。
那么结果将如下所示,这取决于您在声明类时使用的是virtual/override还是new。
using System;
using System.Text;
namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2
// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2
// The following two calls produce different results, depending
// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public virtual void Method2()
{
Console.WriteLine("Base - Method2");
}
}
class DerivedClass : BaseClass
{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?
- c#对象列表,我如何得到一个属性的和