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

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 修饰子类方法

相关文章:

你感兴趣的文章:

标签云: