C# 新建和覆盖的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1399127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between new and override
提问by Shiraz Bhaiji
Wondering what the difference is between the following:
想知道以下之间有什么区别:
Case 1: Base Class
案例 1:基类
public void DoIt();
Case 1: Inherited class
案例一:继承类
public new void DoIt();
Case 2: Base Class
案例 2:基类
public virtual void DoIt();
Case 2: Inherited class
案例二:继承类
public override void DoIt();
Both case 1 and 2 appear to have the same effect based on the tests I have run. Is there a difference, or a preferred way?
根据我运行的测试,案例 1 和案例 2 似乎具有相同的效果。有什么区别,还是首选方式?
采纳答案by rahul
The override modifier may be used on virtual methods and must be used on abstract methods. This indicates for the compiler to use the last defined implementation of a method. Even if the method is called on a reference to the base class it will use the implementation overriding it.
override 修饰符可用于虚拟方法,并且必须用于抽象方法。这表明编译器使用方法的最后定义的实现。即使在对基类的引用上调用该方法,它也会使用覆盖它的实现。
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public override void DoIt()
{
}
}
Base b = new Derived();
b.DoIt(); // Calls Derived.DoIt
will call Derived.DoIt
if that overrides Base.DoIt
.
将调用Derived.DoIt
如果覆盖Base.DoIt
。
The new modifier instructs the compiler to use your child class implementation instead of the parent class implementation. Any code that is not referencing your class but the parent class will use the parent class implementation.
new 修饰符指示编译器使用您的子类实现而不是父类实现。任何不引用您的类但父类的代码都将使用父类实现。
public class Base
{
public virtual void DoIt()
{
}
}
public class Derived : Base
{
public new void DoIt()
{
}
}
Base b = new Derived();
Derived d = new Derived();
b.DoIt(); // Calls Base.DoIt
d.DoIt(); // Calls Derived.DoIt
Will first call Base.DoIt
, then Derived.DoIt
. They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
会先调用Base.DoIt
,然后Derived.DoIt
。它们实际上是两个完全独立的方法,它们碰巧具有相同的名称,而不是覆盖基本方法的派生方法。
Source: Microsoft blog
来源:微软博客
回答by nothrow
try following: (case1)
尝试以下操作:(案例1)
((BaseClass)(new InheritedClass())).DoIt()
Edit: virtual+override are resolved at runtime (so override really overrides virtual methods), while new just create new method with the same name, and hides the old, it is resolved at compile time -> your compiler will call the method it 'sees'
编辑:virtual+override 是在运行时解析的(所以覆盖真的会覆盖虚方法),而 new 只是创建具有相同名称的新方法,并隐藏旧的,它在编译时解析 -> 你的编译器会调用它的方法'看到'
回答by tvanfosson
In the first case you are hiding the definition in the parent class. This means that it will only be invoked when you are dealing with the object as the child class. If you cast the class to its parent type, the parent's method will be invoked. In the second instance, the method is overridden and will be invoked regardless of whether the object is cast as the child or parent class.
在第一种情况下,您将定义隐藏在父类中。这意味着只有在您将对象作为子类处理时才会调用它。如果将类转换为其父类型,则将调用父类的方法。在第二个实例中,该方法被覆盖,并且无论对象是被转换为子类还是父类都会被调用。
回答by Jon B
virtual: indicates that a method may be overriden by an inheritor
virtual: 表示一个方法可以被继承者覆盖
override: overrides the functionality of a virtual method in a base class, providing different functionality.
override:覆盖基类中虚拟方法的功能,提供不同的功能。
new: hidesthe original method (which doesn't have to be virtual), providing different functionality. This should only be used where it is absolutely necessary.
new:隐藏原始方法(不必是虚拟的),提供不同的功能。这应该只在绝对必要的情况下使用。
When you hide a method, you can still access the original method by up casting to the base class. This is useful in some scenarios, but dangerous.
当你隐藏一个方法时,你仍然可以通过向上转换到基类来访问原始方法。这在某些情况下很有用,但很危险。
回答by Shannon Cornish
The difference between the two cases is that in case 1, the base DoIt
method does not get overridden, just hidden. What this means is that depending on the type of the variable depends on which method will get called. For example:
两种情况之间的区别在于,在情况 1 中,基本DoIt
方法不会被覆盖,只是被隐藏。这意味着取决于变量的类型取决于将调用哪个方法。例如:
BaseClass instance1 = new SubClass();
instance1.DoIt(); // Calls base class DoIt method
SubClass instance2 = new SubClass();
instance2.DoIt(); // Calls sub class DoIt method
This can be really confusing and results in non expected behaviour and should be avoided if possible. So the preferred way would be case 2.
这可能会令人困惑并导致非预期行为,如果可能的话应该避免。所以首选的方式是情况 2。
回答by Matthew Whited
In case 1 if you used call the DoIt() method of the inherited class while the type is declared as the base class you will see the action of the base class even.
在第一种情况下,如果您使用调用继承类的 DoIt() 方法,而将类型声明为基类,您甚至会看到基类的操作。
/* Results
Class1
Base1
Class2
Class2
*/
public abstract class Base1
{
public void DoIt() { Console.WriteLine("Base1"); }
}
public class Class1 : Base1
{
public new void DoIt() { Console.WriteLine("Class1"); }
}
public abstract class Base2
{
public virtual void DoIt() { Console.WriteLine("Base2"); }
}
public class Class2 : Base2
{
public override void DoIt() { Console.WriteLine("Class2"); }
}
static void Main(string[] args)
{
var c1 = new Class1();
c1.DoIt();
((Base1)c1).DoIt();
var c2 = new Class2();
c2.DoIt();
((Base2)c2).DoIt();
Console.Read();
}
回答by saba
If keyword override
is used in derive class then its override the parent method.
如果override
在派生类中使用关键字,则它会覆盖父方法。
If Keyword new
is used in derive class then derive method hided by parent method.
如果new
在派生类中使用关键字,则派生方法被父方法隐藏。
回答by Ken Falk
The functional difference will not be show in these tests:
这些测试中不会显示功能差异:
BaseClass bc = new BaseClass();
bc.DoIt();
DerivedClass dc = new DerivedClass();
dc.ShowIt();
In this exmample, the Doit that is called is the one you expect to be called.
在这个例子中,被调用的 Doit 就是你期望被调用的那个。
In order to see the difference you have to do this:
为了看到差异,你必须这样做:
BaseClass obj = new DerivedClass();
obj.DoIt();
You will see if you run that test that in the case 1 (as you defined it), the DoIt()
in BaseClass
is called, in case 2 (as you defined it), the DoIt()
in DerivedClass
is called.
您将看到如果您运行该测试,在案例 1(如您定义的那样)DoIt()
中BaseClass
调用 in,在案例 2(如您定义的那样)DoIt()
中DerivedClass
调用in 。
回答by Ken Falk
I had the same question and it's really confusing,
you should consider that overrideand newkeywords working only with objects of type base class and value of derived class. In this case only you'll see the effect of override and new:
So if you have class A
and B
, B
inherits from A
, then you instantiate an object like this:
我有同样的问题,这真的很令人困惑,您应该考虑override和new关键字仅适用于基类类型的对象和派生类的值。在这种情况下,只有你会看到 override 和 new 的效果:所以如果你有class A
and B
,B
继承自A
,那么你像这样实例化一个对象:
A a = new B();
Now on calling methods will take its state into consideration. Override: means that it extends the function of the method, then it uses the method in the derived class, whereas newtell the compiler to hide the method in the derived class and use the method in the base class instead. Here is a very good sight to that subject:
现在调用方法将考虑其状态。 Override:意味着它扩展了方法的功能,然后使用派生类中的方法,而new告诉编译器隐藏派生类中的方法并使用基类中的方法。这是该主题的一个很好的视角:
回答by snr
new
means respect your REFERENCE type(left-hand side of=
) , thereby running reference types's method. If redefined method doesn't havenew
keyword, it is behaved as it has. Moreover, it also known as non-polymorphic inheritance. That is, “I'm making a brand new method in the derived class that has absolutely nothing to do with any methods by the same name in the base class.” - by said Whitakeroverride
, which must be used withvirtual
keyword in its base class, means respect your OBJECT type(right-hand side of=
), thereby running method overriden in regardless of reference type. Moreover, it also known as polymorphic inheritance.
new
意味着尊重您的 REFERENCE type(left-hand side of=
) ,从而运行引用类型的方法。如果重新定义的方法没有new
关键字,则其行为与其一样。而且,它也被称为非多态继承。也就是说,“我正在派生类中创建一个全新的方法,它与基类中的任何同名方法完全无关。” - 惠特克说override
,必须virtual
在其基类中与关键字一起使用,意味着尊重您的 OBJECT 类型( 的右侧=
),从而在不考虑引用类型的情况下运行覆盖的方法。此外,它也被称为多态继承。
My way to bear in mind both keywords that they are opposite of each other.
我记住这两个关键字的方式是它们彼此相反。
override
: virtual
keyword must be defined to override the method. The method using override
keyword that regardless of reference type(reference of base class or derived class) if it is instantiated with base class, the method of base class runs. Otherwise, the method of derived class runs.
override
:virtual
必须定义关键字以覆盖该方法。使用override
关键字的方法,无论引用类型(基类或派生类的引用)如果用基类实例化,基类的方法都会运行。否则,派生类的方法运行。
new
: if the keyword is used by a method, unlike override
keyword, the reference type is important. If it is instantiated with derived class and the reference type is base class, the method of base class runs. If it is instantiated with derived class and the reference type is derived class, the method of derived class runs. Namely, it is contrast of override
keyword. En passant, if you forget or omit to add new keyword to the method, the compiler behaves by default as new
keyword is used.
new
: 如果关键字被方法使用,与override
关键字不同,引用类型很重要。如果用派生类实例化,引用类型为基类,则运行基类的方法。如果用派生类实例化,引用类型是派生类,则运行派生类的方法。即,它是override
关键字的对比。顺便说一句,如果您忘记或省略向方法添加新关键字,则编译器的行为默认为使用new
关键字。
class A
{
public string Foo()
{
return "A";
}
public virtual string Test()
{
return "base test";
}
}
class B: A
{
public new string Foo()
{
return "B";
}
}
class C: B
{
public string Foo()
{
return "C";
}
public override string Test() {
return "derived test";
}
}
Call in main:
调用主:
A AClass = new B();
Console.WriteLine(AClass.Foo());
B BClass = new B();
Console.WriteLine(BClass.Foo());
B BClassWithC = new C();
Console.WriteLine(BClassWithC.Foo());
Console.WriteLine(AClass.Test());
Console.WriteLine(BClassWithC.Test());
Output:
输出:
A
B
B
base test
derived test
New code example,
新的代码示例,
Play with code by commenting in one-by-one.
通过一一注释来玩代码。
class X
{
protected internal /*virtual*/ void Method()
{
WriteLine("X");
}
}
class Y : X
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Y");
}
}
class Z : Y
{
protected internal /*override*/ void Method()
{
base.Method();
WriteLine("Z");
}
}
class Programxyz
{
private static void Main(string[] args)
{
X v = new Z();
//Y v = new Z();
//Z v = new Z();
v.Method();
}