override与new的区别

 

(new)“隐藏”,(override)“覆盖”(重写)。不够要弄清楚这两个有什么区别确实也很难,因为它们的子类在使用的父亲的方法的时候根本看不出什么区别,反正子类不管父类是new了还是override了用的都是父类的方法。区别就在于,用父类的类型指针去访问子类的成员的时候有区别。

本质区别就是,一个子类的对象中,如果是new的,那么父类的这个函数地址仍然保留着,同时又提供了一个新的子类的该函数入口地址。也就是说子类对象中同时保存了两个入口地址,父类的该函数地址被“隐藏”,但是它还可以用父类的类型指针访问得到,用子类类型指针访问该函数则进入new出来那个函数入口。

如果是override的,表示对象中的这个地址是被改写的,也就是说子类中只能访问到自己定义的函数了。而base的函数地址我们现在没有办法拿到了,因为函数表这个地址被指向了自己定义的函数。因此只能访问到自身定义的该函数。

ContractedBlock.gif ExpandedBlockStart.gif 实例代码
using System;
using System.Collections.Generic;
using System.Text;

namespace OOT
{

    
public class BaseClass
    {
        
public virtual void Func1()
        {
            Console.WriteLine(
" Base.F1");
        }
    }

    
//改写Base.Func1的入口地址为ChildClass1.Fun1的地址。 
    public class ChildClass1 : BaseClass
    {
        
public override void Func1()
        {
            Console.WriteLine(
" (overrided) C1.myF1");
        }
    }

    
//ChildClass2.Fun1是一个新的入口地址,不会覆盖base.Fun1的地址。 
    public class ChildClass2 : BaseClass
    {
        
public new void Func1()
        {
            Console.WriteLine(
" (new) C2.newF1");
        }
    } 

    
class OOT
    {
        
static void Main(string[] args) 
        { 
            BaseClass ba_c1 
= new ChildClass1(); 
            BaseClass ba_c2 
= new ChildClass2(); 

            
//ChildClass1 c1_c3 = new ChildClass3(); 
            ChildClass1 c1_c1 = (ChildClass1)ba_c1; 
            ChildClass2 c2_c2 
= (ChildClass2)ba_c2; 

            
// override 
            Console.Write("ba_c1:"); 
            ba_c1.Func1(); 
            Console.Write(
"c1_c1:"); 
            c1_c1.Func1(); 

            
// new 
            Console.Write("ba_c2:"); 
            ba_c2.Func1(); 
            Console.Write(
"c2_c2:"); 
            c2_c2.Func1(); 
            Console.ReadLine(); 
        } 
    }
}

 

上面的代码运行结果是:

ba_c1: (overrided) C1.myF1
c1_c1: (overrided) C1.myF1
ba_c2: Base.F1
c2_c2: (new) C2.newF1

可以看到,override的时候,父类指针的该函数地址被改写了,因此不管用父类还是子类的指针,进入的都是子类定义的函数。

而new时,用父类指针访问到的是父类定义的函数,用子类指针访问到的是自己定义的函数。因为对象中两个函数的地址可以用不同类型指针进行获取。


 

override:
函数名: 地址
Base.F1: =C1.F1
C1.F1: ********

new:
Base.F1: ********
C2.F1 : ********

一个子类对象

_______________________________________________
|... ___________________......................................|
|...|父类成员...................| .....子类成员.....................|
|... --------------------- .......................................|
|______________________________________________|

............................|...............................|
..................override一个地址.............new一个地址在此处

请注意:访问成员函数的大概过程可以比喻为,基址->成员函数,->操作符将查函数地址表得到偏移量,返回该成员函数的入口地址,代码跳转到此处。->操作符在访问成员变量时,将返回一个和右边变量的类型像匹配的指针或数据类型。

 

转载于:https://www.cnblogs.com/kimma/archive/2008/09/07/1285857.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值