码迷,mamicode.com
首页 > Windows程序 > 详细

C#为什么要用new 修饰子类方法

时间:2015-07-05 09:39:52      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:


c#为什么要用new 修饰子类方法



在C#中,在子类中用new修饰一个方法的目的就是在子类中用该方法隐藏父类中对应方法,这样,对于同一个方法而言,用父类的实例对像来调用和用子类的实例对象来调用就各不相同,实现了在子类中用子类方法隐藏父类的方法。

现在考虑一种情况,在程序中用子类实例化了一个对象,而现在需要调用该对象对应的父类中的已被子类隐藏了的方法,该如何操作?看以下代码:
class A
{
   public int age;
   public void f()
     {

        age++;

        ...

     }
   
}

class B:A

{

 ...

   public new void f( )
    {

     }

...

}


...


static void Main()
{
   class B b=new B();
   ...
   b.f().
}


在Main中,f方法是对应对class B的方法,而不是class A的f方法。现在有一个需求,执行完了b.f()后,要执行Class A中的f方法。怎么办?按照我以前的做法,再实例化一个A类对象c,再将b对象中的成员的当前值赋给c,再执行c.f()。这就是我的做法,当类很简单时,这种方法也不失为一种方法,但当类很复杂时,要完成前述成员赋值工作是件很恐怖的事,甚至是完不成的事。另外,这样做又生成一个几乎与b对象完全一产的对象,这就对资源的利用效率来说是非常不利的。

那有没有更好的方法呢?其实,有一种很妙的方法可完美解决问题,先上代码:

    ...

   A c=(A)b;

   c.f();


不要轻视,一定要仔细看好上面这两句其貌不扬,古里古怪的语句,里边的道理妙着呢,首先看第一句,

A c=(A)b;

首先要说明的此语句没有产生新的A类实例对象,因为这是浅复制,那c是什么,c就是一个指向b对象所指向的B类实例对象且标识为类A的对象,这话咋就这么绕呢?换句话说,c是一个引用型变量,类型为class A,变量名为c,引用的标的的是b所引用的标的,这种变量我们称为父类声明子类对象引用的变量。

即然c是class A类型的,那么c.f()当然是执行了父类A中的方法了,而且由b所引用的实例对象在执行,现在所有的问题是不是都解决了?

如果你还看不出文中的微妙之中,那实在可能是我没有说清楚,或许这个道理真的很微妙,不细心还真看不出来。为了便于理解,请看以下代码:

    class Animal
    {
        public int age;
        public void call()
        {
            Console.WriteLine("I am an animal.I am {0}", age);
        }
    }


    class Cat : Animal
    {
        public new void call()
        {
            Console.WriteLine("I am a cat.I am {0}", age);
        }
    }
  
    public class Program
    {
        public static void Main()
        {
           Cat cat = new Cat();
           cat.age = 3;
           cat.call();
           Animal cat2 = (Animal)cat;
           cat2.call();
        }
    }


运行的结果是:

技术分享

技术分享

cat2调用call方法显示其年龄也是3岁,可知cat2指向的正是cat指向的。

总结一下,以上代码中b和c指向同一个B类对象,但b可执行B类中的所有方法,c可执行A类中被隐藏了方法,对一个子类实例对象,可再定义一个父类声明子类对象引用的变量,就轻松调用子类对象的new方法和被new方法隐藏的父类方法了。

为了巩固一下理解,将以述稍加变化一下,仍是父类声明子类对象引用的变量的例子。如下:

 public static void Main()
        {
           Animal cat = new Cat();
           cat.age = 3;
           cat.call();
           Cat cat2 =(Cat)cat;
           cat2.call();
        }

运行结果为:

技术分享
技术分享


注意:C#可以定义父类声明子类对象引用的变量,但不可以反过来定义子类声明父类对象引用的变量。比如以下代码是无法通过编译的。

A a=new A();

B c=(B)a

这也很好理解,实例对象是按照父类生成的,其中是肯定没有子类的东西的。


再总结,只有父类声明子类对象引用的变量的概念和子类方法new 声明配合起来,才能实现在子类对象中即可使用新方法代隐藏(代替)父类中的方法,也可方便地使用被隐藏的方法。这也许就是C#中为什么要用new 修饰子类方法的主要原因。new的这个作用是override无法提供的。


版权声明:本文为博主原创文章,未经博主允许不得转载。

C#为什么要用new 修饰子类方法

标签:

原文地址:http://blog.csdn.net/jhycjhyc/article/details/46757471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!