zoukankan      html  css  js  c++  java
  • 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();
            }
         }
       }
  • 相关阅读:
    [android] 帧布局
    [android] 表格布局和绝对布局
    使用LVS实现负载均衡原理及安装配置详解
    学习Docker之Dockerfile的命令
    使用docker-compose部署nginx
    CentOS Bash 命令补全增强软件包 bash-completion
    “三次握手,四次挥手”你真的懂吗?
    0777 0的意思
    linux文件或目录权限修改后如何恢复(备份了权限就能恢复)
    centos7进入单用户模式
  • 原文地址:https://www.cnblogs.com/qiuyeyaozhuai/p/2719068.html
Copyright © 2011-2022 走看看