尔冬橙

博客园 首页 新随笔 联系 订阅 管理

1.override

在C#中override可以叫重写或覆盖。意思就是覆盖了父类中跟子类中签名相同的虚方法。

public class A
{    
    public A()    
    {       
         Console.WriteLine('A');    
    }    
    public virtual void Fun()   
    {        
         Console.WriteLine("A.Fun()");    
    }
}
public class B : A
{    
    public B()    
    {
        Console.WriteLine('B');    
    }    
    public override void Fun()    
    {
        Console.WriteLine("B.Fun()");    
    }
}

a).声明B类型的对象:

B test = new B();

test.Fun();

输出结果是:

A

B

B.Fun()

该结果中,先输出A,在输出B,说明实例化子类的对象时,先调用父类的构造函数,再调用子类的构造函数。

b.)声明父类的引用指向子类的对象:

A test = new B();

test.Fun();

运行结果:

A

B

B.Fun()

输出结果和刚才一样。

当使用override时,父类的虚函数完全被子类的函数给“覆盖”了。

c.) 声明父类的对象:

A a = new A();

a.Fun();

输出结果:

A

A.Fun()

此时调用的是父类中的虚方法。

总结:如果在子类中没有override父类的虚方法。则调用父类中的方法。如果子类override了父类的虚方法,则子类的对象使用子类中定义的方法。父类的虚方法被重写或者说覆盖了。

2.new

 在子类中创建一个新的和父类中同名的属性或方法。在子类中隐藏了父类中的属性或方法。

public class A
{
    public A()
    {
        Console.WriteLine('A');
    }
    public virtual void Fun()
    {
        Console.WriteLine("A.Fun()");    
    }
}
public class B : A
{
    public B()
    {
        Console.WriteLine('B');
    }
    public new void Fun()
    {
        Console.WriteLine("B.Fun()");
    }
}

声明B类型的对象:

B test = new B();

test.Fun();

输出结果是:

A

B

B.Fun() ----此时与override的效果相同

声明A类型的对象:

A test = new B();

test.Fun();

运行结果:

A

B

A.Fun() ----此时,与override的情况不一样了。。。

结论:

1.new声明的方法,当使用子类的类型来调用的时候,它会运行子类中的函数,当类型是基类的话 ,则使用基类的函数来执行,可以简单的记忆:

override--覆盖(父类的没了,始终是儿子),new--新的(父子共存)

PS:只有使用virtual定义基类中的函数,并使用override标记子类的函数,才可以达到多态类----始终调用子类的方法

2.子类中override父类的方法,父类的方法一定要是virtual,而在子类中new父类的方法,父类的方法不一定要是virtual

3.抽象类中的抽象方法,必须要被子类override,不能new

4.override可以与sealed关键词连用: sealed override void F(),而new不行。被sealed修饰过的方法,不能再被子类重写。

再来一道复杂点的网上看到的面试题:

public class A
{
    public virtual void Fun1(int i)
    {
        Console.WriteLine(i);
    }
    public void Fun2(A a)
    {
        a.Fun1(1);
        Fun1(5);
    }
}public class B : A
{
    public override void Fun1(int i)
    {
        base.Fun1(i + 1);
    }
}  
 

B b = new B();

A a = new A();

a.Fun2(b);

b.Fun2(a);

运行上面语句,执行结果是什么?

先分析a.Fun2(b):传入的参数是B类型的,因此a.Fun1(1)执行的是B类型对象的Fun1方法,运行结果是2

然后执行Fun1(5),由于运行的是A类型对象的Fun2方法,Fun1自然就是A中的Fun1,运行结果是5

再分析b.Fun2(a):传入的参数是A类型的,因此a.Fun1(1)执行的是A类型对象的Fun1方法,运行结果是1

然后运行Fun1(5),由于运行的是B类型对象的Fun2方法,此时的Fun1已经被B覆盖掉了,因此执行的是被覆盖后的方法,运行结果是6 

那么如果把B类中的override改成new,情况会是什么样呢?

 

由于public void Fun2(A a)的参数类型始终是A类型(当传入B类型时,会转成A类型,相当于A a =  new B()的效果),而用new不会覆盖父类的方法,因此结果是:

1

5

1

5

posted on 2012-05-25 17:00  尔冬橙  阅读(334)  评论(0编辑  收藏  举报