马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

C#的多态性

  [复制链接]
查看4652 | 回复8 | 2016-7-22 08:22:48 | 显示全部楼层 |阅读模式
      在面向对象编程中继承性和多态性是重要机制,今天我就跟大家分享下我对“多态性(C#)”的理解。
      首先我们先来看看多态的定义,同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
      C#中多态分为两种形式,一种是编译的多态,一种是运行的多态;而所涉及到多态的有重载、重写、虚方法、抽象方法和隐藏方法。
      下面来看看这一段代码,我们从代码中来分析他们的概念及区别:
   public abstract class A
  {
         public abstract void prind();
  }
  public class B:A
      {
           public override void prind()
            {
                  Console.WriteLine("我是B类,我重写了A类的抽象方法prind()");
            }
            public virtual void Bprind()
            {
                   Console.WriteLine("我是B类中的虚方法,我可以被继承B类的派生类重写");
            }
            public void Nprind()
            {
                  Console.WriteLine("Nprind");
            }
   }
   public class C:B
   {
         public override Bprind()
         {
              Console.WriteLine("我重写了B类的虚方法Bprind");
         }
          new  public void Nprind()
          {
                Console.WriteLine("我是隐藏Nprind");
          }
         /* 下面是另一种隐藏方法的表现形式
          public new void Nprind()
          {
                Console.WriteLine("我是隐藏Nprind");
          }
         */
          public void Cprind()
         {
               Console.WriteLine("我是Cprind方法");
         }
         public void Cprind(string str)
         {
               Console.WriteLine(str+"我被重载了");
         }
    }
    class D
    {
         static void Main(string []arge)
         {  
              B b=new B();
              B bc=new C();
              C c=new C();
             //重写抽象方法
              b.prind();
             //重写虚方法
              b.Bprind();
              bc.Bprind();
             //隐藏方法
              b.Nprind();
              bc.Nprind();
              c.Nprind();
             //重载
              bc.Cprind();
              bc.Cprind("E");
              Console.Read();
         }
    }
输出结果:
我是B类,我重写了A类的抽象方法prind()
我是B类中的虚方法,我可以被继承B类的派生类重写
我重写了B类的虚方法Bprind
Nprind
Nprind
我是隐藏Nprind
我是Cprind方法
E我被重载了
如果单看这段代码可能会看的很费力,所以我们来听听类他们之间的对话。
D:A类因为你是抽象类,所以你可以定义抽象方法,定义的抽象方法prind可以被继承你的子类重写;因此B类可以重写你的抽象方法prind。
A:我可以被继承我的子类B重写,哪么我也可以被其他的子类重写咯,也就是说我使用了多态性。
D:是的你使用了多态性中涉及的抽象方法,因为你的所有子类都可以对你的抽象方法重写,所以你符合了多态性的定义;但你的所有子类都要注意,重写你的抽象方法必须要用到override关键字、修饰符要相同、传递的参数个数和类型也都要一样及方法的返回值都要一样。

D:B类你自身的Bprind方法是虚方法也可以被继承你的子类重写,不过你和A类不同的是,你自身也可以调用这个虚方法。
B:为什么Bprind会是虚方法呢?它和别的方法也没什么不同啊,只是多了个virtual关键字而已,难道加了virtual关键字的就是虚方法?
D:对的,虚方法就是必须要加上virtual关键字,而没有加virtual或别的关键字的我们叫它为非虚方法;也是因为是虚方法才可以重写,非虚方法是不能重写的;但要注意只有继承你的子类才可以重写你的虚方法。
B:哦,所以C类可以重写我的Bprind这个虚方法。

D:C类你不但重写了父类B的虚方法,还把B类中的Nprind方法写在了隐藏方法了,而已还对自身的Cprind方法进行了重载。
C:听到你跟A、B类的对话我知道了我是重写了虚方法,但这个隐藏方法和重载了Cprind方法,又是什么回事呢?
D:隐藏方法和重写方法差不多,只是关键字不是override,而改成了new;还有不同的是new可以在修饰符前或后。而重载是在同一个作用域中使用了相同的方法名,修饰符、返回值、参数都可以不相同。
C:隐藏方法我自己能调用吧,但如果实例化父类时引用的是我,哪么调用的应该是我的还是父类的方法呢?
D:隐藏方法你自己可以,但只有是对你自己实例时调用的才是你,而如果父类实例时引用的是你,哪么调用的将是父类的方法。

      首先我们先从他们对话和给合代码来看看,重载与重写的区别:
                                            重载:                                                 重写:
             修饰符                    可以不同                                              必须相同                       
       参数个数及类型               可以不同                                              必须相同
            返回值                     可以不同                                              必须相同
            方法名                     必须相同                                              必须相同

      接下来我们来看看抽象方法、隐藏方法、虚方法的注意事项:
       抽象方法:
       1.在基类中定义,派生类中重写。
       2.抽象方法只有在抽象类中才可使用。
       3.抽象类不能实例化。
       4.必须使用abstract。
       隐藏方法:
       1.派生类中定义的和基类中的某个方法名相同。
       2.父类调用父类的方法,而子类调用子类的方法。
       3.使用new关键字,虚方法也能使用。
        虚方法:
        1.在父类中定义的,子类可以重写。
        2.使用virtual关键字。
        注:父类自身也可调用。
ibcadmin | 2016-7-22 09:21:02 | 显示全部楼层
顶一下  但是其实代码文章是可以高亮显示的,在编辑器中 , 倒数第二个工具

点评

下次就在这里写教程了  详情 回复 发表于 2016-7-22 09:35
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
Amy尾巴 | 2016-7-22 09:31:20 | 显示全部楼层
666

点评

7777  详情 回复 发表于 2016-7-22 09:36
剑弑 | 2016-7-22 09:35:58 | 显示全部楼层
ibcadmin 发表于 2016-7-22 09:21
顶一下  但是其实代码文章是可以高亮显示的,在编辑器中 , 倒数第二个工具

下次就在这里写教程了
剑弑 | 2016-7-22 09:36:14 | 显示全部楼层
ibcadmin | 2016-7-22 09:37:04 | 显示全部楼层
剑弑 发表于 2016-7-22 09:35
下次就在这里写教程了

在这里写原创教程 是发钱的

点评

我想想写什么教程先  详情 回复 发表于 2016-7-22 10:15
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
剑弑 | 2016-7-22 10:15:29 | 显示全部楼层
ibcadmin 发表于 2016-7-22 09:37
在这里写原创教程 是发钱的

我想想写什么教程先
暗暗地 | 2018-5-14 20:55:11 | 显示全部楼层
不懂,bc不是B类的实例吗,怎么可以调用C类的Cprind()方法

点评

因为bc的实例声明是C类,所以bc可以对C类中的方法调用  详情 回复 发表于 2018-5-17 09:54
剑弑 | 2018-5-17 09:54:37 | 显示全部楼层
暗暗地 发表于 2018-5-14 20:55
不懂,bc不是B类的实例吗,怎么可以调用C类的Cprind()方法

因为bc的实例声明是C类,所以bc可以对C类中的方法调用
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则