C# 我对多态的理解

面向对象三大宝,继承,封装和多态。

 

多态,是面向对象里面比较难理解的基础部分。听完老蒋的课后,我有一些自己对多态的理解,写在这里。

  提到多态,就不得不说面向对象。那么什么是面向对象呢?

  照我的理解,面向对象就是描述和封装我们所处世界的一种方法,简单的说,就是映射世界,万物皆对象。

  而面向对象的伟大这时候就得以显现了一些,一个连世界都能映射出的方法,还有什么是不能做的?

  面向对象把我们所能看到的一切东西都看做实例,而我们给这些东西起的名字就是对这些东西的抽象,就是类。笼统点的名字就是抽象类,比如动物;具体一点的就 是继承自抽象类的父类,比如猫;而再具体一点就是继承父类的子类,比如波斯猫;注意了,到现在为止,我们所说的类都是抽象类(或者是没有实例化的类,随 你),这个抽象类包含着异常复杂的属性(每一个属性都是一个枚举变量)和人们所能理解的方法。那么好了,这时候,你就可以有一个活生生的自波斯猫类实例话 的小猫了,我们给它的名字这个属性赋值:“小花”。

  而至于你的小花的眼睛是什么颜色,毛发什么颜色这些就取决于上帝给它对应的属性赋什么值了,由于这些属性都是枚举变量,所以没办法,你的小花怎么也个性不 起来,因为这些枚举变量的值都是根据人们的经验所总结出来的。而至于你的小花喜欢尿床,可以认字什么的,就看你让它实现什么接口了。这些都不属于今天想写 的内容,所以就此略过了。

  多态的语义看似复杂,其实说起来不外乎两种方式,一个是隐藏方法(new),一个是重写方法(override)。

1.隐藏方法
  隐藏方法指的是通过在子类中用new关键字,对父类的同签名方法实现隐藏,实现当子类实例赋值给父类实例后,通过父类实例调用该方法实际调用的是父类实现的方法这一功能。
  例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    class MyBase
    {
        public void Func()
        {
            Console.WriteLine("我是父类方法");
        }
    }
    class MyDerive:MyBase
    {
        public new void Func()
        {
            Console.WriteLine("我是子类方法");
        }
    }

    class Test
    {
        static void Main(string[] args)
        {
            MyBase mybase = new MyBase();
            mybase.Func();

            MyDerive myderive = new MyDerive();
            myderive.Func();


            mybase = myderive;
            mybase.Func();

            Console.ReadLine();
        }
    }
}

输出:
     我是父类方法
     我是子类方法
     我是父类方法
   
 

2.重写方法
  重写方法指的是通过在子类中使用override关键字对,对父类使用virtual关键字修饰的同签名方法进行重写
,实现当子类实例赋值给父类实例后,通过父类实例调用该方法实际是调用子类实现的方法这一功能。

  例子:注意这两个例子代码的区别很小,但是结果却很不一样
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    class MyBase
    {
        public virtual void Func()
        {
            Console.WriteLine("我是父类方法");
        }
    }
    class MyDerive:MyBase
    {
        public override void Func()
        {
            Console.WriteLine("我是子类方法");
        }
    }

    class Test
    {
        static void Main(string[] args)
        {
            MyBase mybase = new MyBase();
            mybase.Func();

            MyDerive myderive = new MyDerive();
            myderive.Func();


            mybase = myderive;
            mybase.Func();

            Console.ReadLine();
        }
    }
}

输出:
    我是父类函数
    我是子类函数
    我是子类函数

你看,多态,就是这么简单。

    或许又要纳闷多态在编程上的使用,我就再举个不恰当的例子吧。

    现在大学不都开学么,我们把大学里的每个人都看做从“人”这个抽象类继承的子类。这些子类通过实现不同接口又分为 学生类 和 教官类。

    好了,军训开始了。

    军训训谁,谁训呢?于是我们new了一个 教官对象 “小张”  和 一群 学生对象 “愣头青们”。

    然后军训先训站姿,一开始“愣头青们”都由着自己的性子,也就是自己实现stand()方法,随便站着。这时候“小张”一看不愿意了,于是说:“每个人都 给我站好了”。于是,“愣头青们”开始按照原始的站姿站好了。军训到中午了,“小张”又叫每个人实现Eat()方法,也就是都去吃饭了。

    看懂 Eat()和Stand()方法哪个应该用重写,哪个应该用隐藏了么?
    还不明白的话,我就写段伪代码,来解释下我上面的这段大白话。
   
   class Person
   {
      public virtual void Eat();
      public  void Stand()
      {
            //标准站法
      }
   }
   class Student:Person,IStudentAble
   {
      public new void Stand()
     {
        //每个人站姿不一样
     }
     public override void Eat()
     {
        //每个人吃饭口味不一样
     }
   }
   class Master:Person,IMasterAble
   {
   }
    class 大学生活
   {
      public void 军训()
     {
        Master 小张=new Master();
        Student[] 愣头青们={"张三","李四","王五"};

        //教官小张没来前,大家随便站
        for(int i=0;i<愣头青们.Length,i++)
        {
            愣头青们[i].Stand();
        }

       //教官小张来了,要求每个人都站好了
        Person[] per=愣头青们;
        for(int i=0;i<per.Length,i++)
        {
            per们[i].Stand();
        }
       

        //到中午了,教官小张说,每个人去吃饭
        Person[] per2=愣头青们;
        for(int i=0;i<per2.Length,i++)
        {
            per2[i].Eat();
        }
     }
   }
posted @ 2012-10-10 21:53  ζ老豆角  阅读(356)  评论(0编辑  收藏  举报