virtual与new virtual有本质区别嘛?

微创社(MCC) 2009-08-04 10:05:51
virtual与new virtual有本质区别嘛?(警告会有不同,但不算本质区别)

在多态的表现上,感觉上是一样的,
如果有区别,能给出反证嘛?


using System;

namespace PCTest
{
public class ClassB
{
public new virtual void GetName()
{
Console.WriteLine("GetName:ClassB!");
}
}

public class ClassBB : ClassB
{
public new virtual void GetName()
{
Console.WriteLine("GetName:ClassBB!");
}
}

public class ClassBBB : ClassBB
{
public new virtual void GetName()
{
Console.WriteLine("GetName:ClassBBB!");
}
}

//abstract|virtual|override|new|[]|new virtual|null
//
//abstract->override
//virtual->[]|virtual|override|new virtual|override|new
//[]->[](=new)|new|virtual|new virtual
//override->[](=new)|new|virtual|new virtual|override
//new->[](=new)|new|virtual|new virtual
//new virtual->[]|virtual|override|new virtual|override|new
//
//abstract :当前不实现,不覆写基类,不能被重写, 必须覆写
//[]|new : 当前实现,不覆写基类, 能被重写,不能被覆写,[]会有警告
//virtual : 当前实现,不覆写基类, 能被重写, 能被覆写,会有警告//
//new virtual: 当前实现,不覆写基类, 能被重写, 能被覆写,会有警告//
//override : 当前实现, 覆写基类, 能被重写, 能被覆写


public class Test
{
static void Main()
{
//建立对象
ClassB a = new ClassB(); a.GetName();
ClassBB aa = new ClassBB(); aa.GetName();
ClassBBB aaa = new ClassBBB(); aaa.GetName();

//
ClassB b;
ClassB bb;

b = aa; b.GetName();
b = aaa; b.GetName();
bb = aaa; bb.GetName();

//End
Console.ReadKey();
}
}
}
...全文
361 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
小D 2010-06-18
  • 打赏
  • 举报
回复
Class A
Class B:A

A中有一个方法,B继承了A中的方法,但不想实现A中的方法,他可以直接修改里面的方法,但在B中方法的下面会出现一条警告波浪线,,,这时,可以在B类的方法前面加上 new 就可以轻松解决,,,,,

也可以在A类中的方法前面加上 virtual 在B类方法中加上 override 也可以轻松解决~!~!

希望能有帮助~!
微创社(MCC) 2009-08-05
  • 打赏
  • 举报
回复
logxing 说的不错,我是想确认一下。

其实可以这样来看待 new 的作用

void fun()
new void fun()

virtual fun()
new virtual void fun()

这两组修饰的区别在于new是经过了"显式"的确认,在重写时不出现警告。
如果去除new的确认功能,我们更可以理解为new其实没有产生对多态的影响作为。
而单独的new远全可以当作无修饰,
这样的话,这七种修饰关系就相当容易理解了。

tabbycat 的观点不认同
首先new是非常必要的,有确认的功能(这个不针对你的问题)
其次new有版本控制的作用,我在3楼给出了一些解释

对以下七种修饰作一个总结:
|virtual|override||[]|new virtual|null
--------
new:特殊的确认作用(注意:这样解释仅仅是为了便于理解)
null(没有函数):自然继承
abstract:比较好理解
--------
[]:重写
override:
virtual=new virtual=[]+override

另:在多态的理解上,要注意对象的两个状态
ClassB a = new ClassBB();
(一)变量的类型ClassB
(二)对象的类型ClassBB
其规则是:C#一旦发现虚方法,就不去查看继承的层次,虚方法被当成虚拟分派(dispatch)
tabbycat 2009-08-05
  • 打赏
  • 举报
回复
避免用new 用new很容易出BUG的
当你不得不用new的时候,你的OO设计就已经出问题了
logxing 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pcnetman888 的回复:]
引用 7 楼 logxing 的回复:
new virtual 是隐藏了基类的同名方法,同时说明该类的派生类可以重写该方法。


那virtual呢,
从表现上,同样是隐藏了基类的同名方法.

我们需要了解是两者是区别
[/Quote]

我知道你问得什么了。
在派生类中 你写new virtual和virtual没有任何区别,两者都是隐藏基类同名方法,只不过后者有一个警告而已。这和一般的 new methordname和methordname一样。
微创社(MCC) 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 dancingbit 的回复:]
那virtual呢,
从表现上,同样是隐藏了基类的同名方法.
-------------------------------
看来你对virtual的理解还有问题:

virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
虚拟成员的实现可由派生类中的重写成员更改。
[/Quote]

同样感谢gjl370825对virtual的解释

!!!我们现在要讨论的不是virtual有什么用处(所括override)
(好象大家都是冲着这个来的,不客气的说,这个只是初级阶段,如果不了解virtual和override的用法,就不能把握多态的性质)

而是能够说清楚virtual与new virtual的"本质"区别.
gjl370825 2009-08-05
  • 打赏
  • 举报
回复
你可以这样的理解:

virtual:
virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。(自MSDN)
而与virtual对应的为override,重写其父对象里的方法
给你举下例吧

class a{
public virtual void say{
Console.WriteLine("这里是aa!");
}
}
class b:a{
public override void say{
Console.WriteLine("这里是bb,aa被替换了!");
}
}
class c:a{
public override void say{
Console.WriteLine("这里是cc,aa被替换了!");
}
}

那么:
a _a = new b();
_a.say();//打印出,这里是bb,aa被替换了



new:(摘自MSDN)
在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员意味着该成员的派生版本将替换基类版本。在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。使用 new 显式隐藏成员会取消此警告,并记录代之以派生版本这一事实。
若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并使用 new 修饰符修饰该成员。

public class BaseC
{
public int x;
public void Invoke() {}
}
public class DerivedC : BaseC
{
new public void Invoke() {}
}
在此示例中,DerivedC.Invoke 隐藏了 BaseC.Invoke。字段 x 不受影响,因为它没有被类似名称的字段隐藏。
对同一成员同时使用 new 和 override 是错误的,因为这两个修饰符在含义上相互排斥。使用 new 会用同样的名称创建一个新成员并使原始成员变为隐藏的,而 override 则扩展继承成员的实现。




wtboy 2009-08-05
  • 打赏
  • 举报
回复
关注中。。。。
dancingbit 2009-08-05
  • 打赏
  • 举报
回复
那virtual呢,
从表现上,同样是隐藏了基类的同名方法.
-------------------------------
看来你对virtual的理解还有问题:

virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
虚拟成员的实现可由派生类中的重写成员更改。

微创社(MCC) 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 logxing 的回复:]
new virtual 是隐藏了基类的同名方法,同时说明该类的派生类可以重写该方法。
[/Quote]

那virtual呢,
从表现上,同样是隐藏了基类的同名方法.

我们需要了解是两者是区别
logxing 2009-08-05
  • 打赏
  • 举报
回复
new virtual 是隐藏了基类的同名方法,同时说明该类的派生类可以重写该方法。
微创社(MCC) 2009-08-05
  • 打赏
  • 举报
回复
再补充一点:
virtual与new virtual,
除了警告上的差异,
还是存在一些“本质性”的小区别。

我会在新开贴中加以阐述
新贴:关于"继承"与"多态"的关系,我们到底理解了有多少.
http://topic.csdn.net/u/20090805/13/254df2c5-2356-438a-a7f5-7f9ce5a9b3b0.html
xiaojia19850414 2009-08-05
  • 打赏
  • 举报
回复
标记,学习。
坏人修 2009-08-05
  • 打赏
  • 举报
回复
鉴定完毕
重写与覆盖,想当初这两个概念混淆了很久。
微创社(MCC) 2009-08-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 czlsb1025 的回复:]
一个是virtual, 一个是新new virtual,重写与履盖的区别

[/Quote]
你的问答不对,应该是这样:
一个是virtual, 一个是新new,重写与履盖的区别
czlsb1025 2009-08-04
  • 打赏
  • 举报
回复
一个是virtual, 一个是新new virtual,重写与履盖的区别
微创社(MCC) 2009-08-04
  • 打赏
  • 举报
回复
呵呵,NEW还是不错的,主要用于版本控制。
基于以下场景:
A公司拥有ClassA
B公司向A公司购买了ClassA
B公司在ClassA的基础上实现了ClassB
B公司在ClassB中增加了ClassA中没有的比如Sort方法并定义为virtual方法
某天A公司的新版本中增加了Sort方法
这时B公司就需将Sort方法改为new virtual方法

btw1:C#一旦发现虚方法,就不去查看继承的层次,虚方法被当成虚拟分派(dispatch)。
btw2:[]代表“方法”前没有修饰,NULL代表子类中没有“方法”(这个很容易理解,所以没有放进例子中)。
CGabriel 2009-08-04
  • 打赏
  • 举报
回复
覆写与遮盖的区别

当然,你的代码把他写到完全一样
  • 打赏
  • 举报
回复
如果你使用new,我会立马放弃。

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧