首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

60分,被NEW关键字捞晕了!两个new 的例中有什么不一样!解决思路

2011-12-29 
60分,被NEW关键字捞晕了!!两个new 的例中有什么不一样!1假如父类中的方法并不是virtual的,子类中的方法

60分,被NEW关键字捞晕了!!两个new 的例中有什么不一样!
<1>
假如父类中的方法并不是virtual的,子类中的方法也就无法使用override关键字进行覆写,而使用new关键字对父类中的方法进行覆盖,覆盖后,父类的对象引用来引用子类的对象时,进行调用该同名方法,会调用父类的方法,虽然实际上引用的是子类的对象。

using   System;
using   System.Collections.Generic;
using   System.Text;

namespace   Hello
{
interface   IHello
{
void   sayHello();
}
class   Hello   :   IHello
{
public   virtual   void   sayHello()
{
Console.WriteLine( "Hello! ");
}
}
class   HelloLee   :   Hello
{
public   override   void   sayHello()
{
Console.WriteLine( "Hello   Lee! ");
}
}
class   HelloCoderLee   :   HelloLee
{
public   new   void   sayHello()
{
Console.WriteLine( "Hello   CoderLee! ");
}
}
class   Program
{
static   void   Main(string[]   args)
{
IHello   sayHello;
sayHello   =   new   HelloCoderLee();
sayHello.sayHello();
Console.ReadLine();
}
}
}

输出为:
Hello   Lee!


<2>
而我查看SDK文档:
使用   new   修饰符显式隐藏从基类继承的成员。
若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,
并用   new   修饰符修饰它。

//   cs_modifier_new.cs
//   The   new   modifier
using   System;
public   class   MyBaseC  
{
      public   static   int   x   =   55;
      public   static   int   y   =   22;
}

public   class   MyDerivedC   :   MyBaseC  
{
      new   public   static   int   x   =   100;       //   Name   hiding
      public   static   void   Main()  
      {
            //   Display   the   overlapping   value   of   x:
            Console.WriteLine(x);

            //   Access   the   hidden   value   of   x:
            Console.WriteLine(MyBaseC.x);

            //   Display   the   unhidden   member   y:
            Console.WriteLine(y);
      }
}
输出
100
55
22


<3>
看msdn:

new   关键字可以显式隐藏从基类继承的成员。
隐藏继承的成员意味着该成员的派生版本将替换基类版本


现在有一问题:为什么 <1> 中是输出Hello   Lee!(父类)

而不是输出Hello   CoderLee!(子类)
new关键字不是说隐藏基类吗,
也就说调用子类


这个例子与 <2> 例有什么不同
为什么 <2> 例中调用的是子类的属性


顺便问一下,怎样才能理清new   的使用

[解决办法]
多态的时候 new 方法就不起作用了

如果要被子类override那就要virtual

new 是不行的 实际上调用的还是父类的方法 这个没办法解决

只有在写父类的时候所有的方法都virtual一下
[解决办法]
new一个是在调用的时候使用,这个就很简单了,就是实力化一个对象。

当new 出现在 类里面 public 前面的时候是不是就晕了呢?其实不用去管它。


> > 为什么 <1> 中是输出Hello Lee!(父类)

这个呢是因为编译的时候,调用的方法的内容就固定了,就是调用父类,不会考虑子类。

而另一种方法就是“动态”的,会考虑子类李重写的方法。

就是这个意思。感觉一下:)
------解决方案--------------------


我来解释你的程序为什么输出了Hello Lee!
你在HelloCoderLee类中用public new void sayHello()实际上是添加了一个新方法这个方法跟你所继承的HelloLee类中的sayHello方法毫无关系,什么叫new呢?等于在这个HelloCoderLee类中存在两个sayHello方法,而
IHello sayHello;
sayHello = new HelloCoderLee();
sayHello.sayHello();
这三句中sayHello实际上是实现了接口IHello,也就是说在sayHello.sayHello();时实际上是调用的HelloLee中的方法,上边说过了HelloCoderLee方法实际上有两个sayHello方法,如果你改成这么写
HelloCoderLee sayHello = new HelloCoderLee();
sayHello.sayHello();
就应该是Hello CoderLee!了

[解决办法]
如果,HelloLee还有其它实现,这样HelloCoderLee也能一一继承下来,不仅限于接口
如果这样声明:class HelloCoderLee : HelloLee
HelloCoderLee只能继承HelloLee对于IHello接口的实现,而不能改写
而class HelloCoderLee : HelloLee,IHello 就可自己实现IHello的接口
[解决办法]
其实这个new的语法是C#里面独有的,而且你不写也不会出错,只会有一个警告。
new的意思是,派生类的方法将隐藏基类的方法,这个隐藏并不是说基类的方法无法调用了,这个隐藏是与重写相对的,隐藏了,当使用基类调用的时候,这个方法就能显现出来。。而重写了,无论你用什么类型调用,总是调用重写的方法,因为方法被“重新写过”了。
[解决办法]
为什么要有这个new,主要是因为程序版本的问题,一般而言,应该现有父类才能有派生类,但使用派生类者当然可以定义自己的方法,比如sayHello,但后来父类发现sayHello这个方法蛮好,也取了同名的方法(父类可不知道它的派生类已经用了这个方法名),那么,显然,如果你用父类的引用调用这个sayHello方法的时候最好还是调用父类自己的,而不是派生类的(这才符合你的程序的本意),当然这也是C#默认的处理方式,但这样编译器好歹在编译的时候会给你一个警告.

我们加上new的意思是告诉编译器 "我知道我在干什么,你别来烦我 ",所以编译器就不哼了

同理这个new出来的方法只有子类对象自己能用的到,所以无论你是使用基类的引用还是接口的引用别人都访问不到.

热点排行