c#继承中的new、virtual、override

1.继承

1.1 定义

 继承是自动地共享基类中所有非私有的方法和数据的机制。

1.2 继承的理解

//假设我现在有两个类,一个是计算机类、另一个是联想计算机类
 class Compute {//计算机类
     public string Color;//颜色
     public double ScreenSize;//屏幕尺寸
     public double MemorySize;//内存大小
   
     public void playGame() //打游戏
     {
         Console.WriteLine("俄罗斯方块");
     }
     public void WatchMovie()//看电影      
     {
         Console.WriteLine("暴风影音播放电影...");
     }
 }
 
class Lenovo: Compute//联想计算机类,联想计算机继承于计算机类
{
    public void WriteDocument()//办公
    {
        Console.WriteLine("写文档...");
    }
} 

按照继承的定义,那么Lenovo类应该能自动获取Compute类内所有非私有的成员,也就是Color、ScreenSize、MemorySize、playGame、WatchMovie。
现在编写测试类如下:

class Test
    {
        static void Main(string[] args)
        {
            Lenovo lenovo = new Lenovo();
            //调用父类里面的方法
            lenovo.WatchMovie();//暴风影音播放电影...
        }
    }

Lenovo lenovo = new Lenovo();创建lenovo对象时,计算机又是怎么操作的尼?
在执行New Lenovo();计算机会分配空间存储Lenovo类中所有非静态的成员,在这个过程中,不仅会为自己本身的WriteDocument方法分配空间,同时还会为从Compute类中继承而来的成员分配空间,如下所示。
在这里插入图片描述
如果我们通过子类去创建父类对象时,计算机又是怎么操作的尼?
在执行new Lenovo();代码时,计算机依然会分配空间存储Lenovo类中所有非静态的成员。
在执行Compute compute = new Lenovo();时,实际上compute对象分配的空间是整个Lenovo类的空间,但是compute对象只能调用属于Compute部分的成员。

//通过子类创建父类对象
Compute compute = new Lenovo();
compute.WatchMovie();
//compute.WriteDocument();//不合法Compute中没有WriteDocument方法

2.new、virtual、override

2.1 new

 new 关键字通常用于创建对象的实例或隐藏继承自基类的成员。

2.2 virtual

 当方法声明中包含virtual修饰符时,方法就被称为虚方法。虚方法定义中不能包含static、abstract或override修饰符。

2.3 override

   当一个实例方法声明包含一个override限定符时,这个方法就用相同的属性覆盖一个被继承的虚拟方法,则此方法被称为覆盖方法。
 需要注意override和virtual是成对出现的,只有虚方法才能被覆盖。

2.4 new、virtual、override的理解

还是刚才的两个类,只不过这个时候,将Compute类中的playGame设为了虚方法。同时在Lenovo类中添加了两个父类中的同名方法,其中playGame使用override修饰、WatchMovie使用new修饰。

class Compute {
    public string Color;//颜色
    public double ScreenSize;//屏幕尺寸
    public double MemorySize;//内存大小
  
   //虚方法
    public virtual void playGame() //打游戏
    {
        Console.WriteLine("俄罗斯方块");
    }
    public void WatchMovie()//看电影
    {
        Console.WriteLine("暴风影音播放电影...");
    }
}

class Lenovo: Compute
{
    //方法的覆盖
     public override void playGame() //打游戏
    {
        Console.WriteLine("LOL");
    }
    //new 修饰的方法

    new public void WatchMovie()//看电影
    {
        Console.WriteLine("优酷播放高清电影...");
    }

    public void WriteDocument()//办公
    {
        Console.WriteLine("写文档...");
    }
}

编写测试类

Class Test
    {
        static void Main(string[] args)
        {
            Lenovo lenovo = new Lenovo();
            //执行Lenovo中的方法
            lenovo.playGame();//LOL
            lenovo.WatchMovie();//优酷播放高清电影...

            Compute compute = new Lenovo();
            //调用的Compute类中的playGame,
            //但是此时Compute类中的playGame已经被lenovo中的playGame覆盖
            //所以表现形式上还是输出lenovo类中的playGame方法
            compute.playGame();//LOL
            compute.WatchMovie();//暴风影音播放电影...
        }
    }

执行 Lenovo lenovo =new Lenovo();计算机会分配空间存储Lenovo类中所有非静态的成员。
对于new修饰的同名方法,计算机会重新分配空间存储Lenovo类中的WatchMovie,并临时隐藏父类中的WatchMovie方法;可以理解为现在联想计算机同时存在两个观影软件,其中“暴风影音”是默认存在的,它在播放一下旧格式电影时有优势,因此有一定存在的必要性;优酷是新安装的,现在主流的播放方式,通常情况下默认使用的都是优酷。只有在特殊强调旧格式电影时才会使用暴风影音(((Compute)lenovo).WatchMovie();)。
对于override修饰的方法,计算机不会重新分配空间,而是和父类(Compute)公用一块存储空间,并将原来的内容给覆盖掉。可以理解为,你觉得原来电脑上默认安装的俄罗斯方块不好玩还占内存,没有存在必要了你就把俄罗斯方块卸载了,并用这块内存安装的LOL,这样原本对应俄罗斯方块的内存变成了LOL。
如下图所示。
在这里插入图片描述
同理当我们执行Compute compute = new Lenovo();计算机依然会分配空间存储Lenovo类中所有非静态的成员。而compute对象只能调用属于Compute部分的成员。
对于方法WatchMovie是没有影响的,使用Compute类自己的;
对于playGame方法,此时对应内存中存储的为Lenovo类的playGame方法。因此,虽然是用compute对象调用自己的playGame方法,但是此时对应内存已经被Lenovo类的playGame方法覆盖了,所以表现形式为使用了Lenovo类的playGame方法。

个人愚见,如有理解错误,还请多多批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值