隐藏函数与虚函数

(1)概述

如果要隐藏函数,要使用new关键字;如果要重写(覆盖)虚函数,要使用virtual和override关键字。

然后讲一下什么是申明类和实例类。举个例子: Bird b = new Magpie();

Bird类就是申明类,而Magpie就是实例类。

 

接下来讲一下调用某个对象的函数的基本规律。该方法可以结合以下几节的实例具体运用。

1、当调用一个对象的函数时,系统会直接去检查这个对象的申明类,看所调用的函数是否为虚函数;

2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。

3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果是有,那么OK,它就不会再找了,而马上执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重写了该虚函数的父类为止,然后执行该父类里重写后的函数。

该规律节选自 http://blog.csdn.net/shamozhu/article/details/3835664

 

(2)隐藏函数:

    class Program
    {
        static void Main(string[] args)
        {
            Bird b = new Bird();
            b.Chirp();
            Magpie m = new Magpie();
            m.Chirp();
            Bird b2 = new Magpie();
            b2.Chirp();
        }
    }

    class Bird
    {
        public void Chirp()
        {
            Console.WriteLine("...");
        }
    }

    class Magpie : Bird
    {
        public void Chirp()
        {
            Console.WriteLine("Magpie ...");
        }
    }

如果想在Magpie类中定义自己的Chirp()方法,也就是说隐藏基类中的同样签名的方法,就需要在派生类中定义相同签名的方法。

但是这样编译器会出现一个警告,提示如果有意去隐藏基类的方法,请使用New关键字修饰。

Warning 1 'InheritanceTest.Magpie.Chirp()' hides inherited member 'InheritanceTest.Bird.Chirp()'. Use the new keyword if hiding was intended.

所以正确的做法是

    class Magpie : Bird
    {
        public new void Chirp()
        {
            Console.WriteLine("Magpie ...");
        }
    }

如果运行该程序,结合概述中的规律,在调用对象的方法时,查看申明类的方法的声明,如果不是虚函数,则直接执行申明类中的方法。

所以在上面那个例子中,输出结果为

...

Magpie ...
...

只有第二次调用的时候使用的是Magpie类作为申明类,所以只有第二次调用的是Magpie.Chirp()的方法

 

(3)虚函数

下面在Bird.Chirp()方法前加上virtual关键字,则该函数成为了虚函数。

    class Program
    {
        static void Main(string[] args)
        {
            Bird b = new Bird();
            b.Chirp();
            Magpie m = new Magpie();
            m.Chirp();
            Bird b2 = new Magpie();
            b2.Chirp();
        }
    }

    class Bird
    {
        public virtual void Chirp()
        {
            Console.WriteLine("...");
        }
    }

    class Magpie : Bird
    {
        public void Chirp()
        {
            Console.WriteLine("Magpie ...");
        }
    }

在以上的例子中,Magpie类的定义方法会使编译器发出警告,对Magpie.Chirp()方法或者使用new关键字,或者使用override关键字。

Warning 1 'InheritanceTest.Magpie.Chirp()' hides inherited member 'InheritanceTest.Bird.Chirp()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. 

下面我们使用new关键字来隐藏父类中的方法,然后看看输出结果是什么。

    class Magpie : Bird
    {
        public new void Chirp()
        {
            Console.WriteLine("Magpie ...");
        }
    }

运行程序,输出结果为:

...

Magpie ...
...

道理同我们在概述中一样。申明类为Bird时,虽然Chirp()是虚函数,但是子类中并没有重写该函数,所以最后还是执行了Bird.Chirp()的方法。申明类为Magpie时,就直接执行了Magpie.Chirp()的方法。

 

如果我们要使用override关键字,就表示我们要对父类中的虚函数重写或者覆盖。   

    class Magpie : Bird
    {
        public override void Chirp()
        {
            Console.WriteLine("Magpie ...");
        }
    }

 

再运行程序,就会得到不同的结果:

...

Magpie ...

Magpie ...

具体原因请结合概述中的规律进行分析。

 

(4)下面做一个练习

    class Program
    {
        static void Main(string[] args)
        {
            Animal animal = new Animal();
            Animal bird = new Bird();
            Animal magpie = new Magpie();
            Animal chicken = new Chicken();
            Chicken c2 = new Chicken();  
            animal.Move();
            bird.Move();
            magpie.Move();
            chicken.Move();            
            c2.Move();
        }
    }

    class Animal
    {
        public virtual void Move()
        {
            Console.WriteLine("Animal move");
        }
    }

    class Bird : Animal
    {
        public override void Move()
        {
            Console.WriteLine("Bird move");
        }
    }

    class Magpie : Bird
    { }

    class Chicken : Animal
    {
        public new void Move()
        {
            Console.WriteLine("Chicken move");
        }
    }

输出结果为:

Animal move

Bird move

Bird move

Animal move

Chicken move

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值