多态及实现方式

1.多态的概念

♦ “多态性” 一词最早用于生物学,指同一种族的生物体虽然具有相同的本质特征,但在不同环境中可能呈现出不同的特性。例如:狗的多态性。

面向对象开发中的多态

  • 在面向对象理论中,多态是同一操作施加于不同的类的实例,不同的类将进行不同的解释,最后产生不同的结果
  • 从编程角度来看,多态表现为同样的程序语句,在不同的上下文环境中可能得到不同的运行结果。

 2.为什么需要多态

♦举例说明:

  • 你领养了一只猫和一只狗,宠物饿了需要你喂食
  • class Master      //定义主人类
    {
        public void Feed(Cat cat)
        {
            cat.Eat();
        }
        public void Feed(Dog dog)
        {
            dog.Eat();
        }
    }
    
    class Cat       //定义猫类
    {
        public void Eat()
        {
            Console.WriteLine("吃鱼");
        }
    }
    
    class Dog     //定义狗类
    {
        public void Eat()
        {
            Console.WriteLine("吃肉");
        }
    }

    如果再领养XXX宠物,就需要给XXX喂食,怎么办?

    • 添加XXX类,继承Pet类,实现吃的方法
    • 修改Matser类,添加给XXX喂食的方法
    • class Master      //定义主人类
      {
          public void Feed(Cat cat)
          {
              cat.Eat();
          }
          public void Feed(Dog dog)
          {
              dog.Eat();
          }
          public void Feed(XXX xxx)
          {
              xxx.Eat();
          }
          
          ... ... ...
      }

      频繁修改代码,代码可扩展性、可维护性差,如何优化?

    • class Master      //定义主人类
      {
          public void Feed(Pet pet)
          {
              pet.Eat();
          }
      }
      
      class Pet        //定义宠物类
      {
          public void Eat()
          {
              Console.WriteLine("吃东西");
          }
      }
      
      class Cat:Pet       //定义猫类
      {
          public void Eat()
          {
              Console.WriteLine("吃鱼");
          }
      }
      
      class Dog:Pet     //定义狗类
      {
          public void Eat()
          {
              Console.WriteLine("吃肉");
          }
      }
      
      class XXX:Pet     //定义XXX类
      {
          public void Eat()
          {
              Console.WriteLine("吃???");
          }
      }
      
      class Program
          {
              static void Main(string[] args)
              {
                  Dog dog = new Dog();
                  Cat cat = new Cat();
                  XXX xxx = new XXX();
                  Master m =new Matser();
                  m.Feed(dog);
                  m.Feed(cat);
                  m.Feed(xxx);
              }    

多态的好处

  • 多态能使代码具有更强的适用性,当需求变化时,可以将需要改动的地方减少到最低限度
  • 多态对已存在代码具有可替换性。例如,对宠物的吃东西的方法,对属于宠物的任何子类都适用

  • 多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作
  • 多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的
  • 多态在应用中体现了灵活多样的操作,提高了使用效率
  • 多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要

3.多态的实现方式

♦多态有三种实现方法:

  • 虚方法:
    • virtual override  //是普通的类,有意义的,可以创建对象
    • 如果子类重写了父类的虚方法,那么通过父类变量来调用这个方法的时候会调用子类的方法
  • 抽象类:
    • abstract override  //只能是抽象类,无意义的,不能创建对象
    • 只声明方法,不去实现方法,让继承的类去实现(光说不做)
  • 接口:
    • Interface只定义方法,只定义规范,让实现这个接口的类,去实现里面的方法
    • 多个类具有相同的行为但没有共同父类可以使用接口

虚方法:很平常的类,只需要在需要重写的方法前面添加virtual,就可以被其子类重写,而virtual本身所在的方法也是有意义,可以使用的。

  • 举例说明:
    • class Employee //父类
      {
          public virtual void DaKa()
          {
              Console.WriteLine("员工九点打卡");
          }
      }
      class Manager: Employee   //子类
      {
      public override void DaKa()
          {
              Console.WriteLine("经理11点打卡");
          }
      }
      
      Employee emp
      = new Manager(); emp.DaKa(); // 经理11点打卡

抽象类:专门用来抽象出公共的方法和属性。进行共用的。所以他是无意义的,不能创建对象。只声明方法,不去实现方法,让继承的类去实现(光说不做),抽象成员只能出现在抽象类中,抽象类中也可以有其他的普通成员。一个子类继承了一个抽象的父类,那么这个子类必须重写这个抽象父类中的所有抽象成员,所以当我们调用对象时,抽象类 ss= new 子类();这个时候我们所能调用的是父类的成员,但是子类重写的成员,就是子类重写后的。

  • 举例说明:
    • abstract class Animal
      {
          public abstract void Shout();
      }
      
      class Cat: Animal
      {
          public override void Shout()
          {
              Console.WriteLine("猫咪喵喵叫...");
          }
      }
      
      class Dog: Animal
      {
          public override void Shout()
          {
              Console.WriteLine("小狗汪汪叫...");
          }
      }
      
      Dog dog = new Dog();
      Cat cat = new Cat();
      dog.Shout();        //猫咪喵喵叫...
      cat.Shout();        //小狗汪汪叫...

接口:接口是一种规范。也是一种能力。只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员。接口的功能要单一。也就是说,接口不能new(不能创建对象)。实现接口的子类必须实现该接口的全部成员。一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。class MyClass:A,IA{},因为类是单继承的。

  • 举例说明:
    • class Driver : Person, IKouLan
      {
          public void KouLan()
          {
              Console.WriteLine("司机也可以扣篮");
          }
      }
      
      interface IKouLan  //表示可以扣篮的一种能力
      {
          void KouLan();
      }
      
      class NBAPlayer : Person
      {
          public void KouLan()
          {
              Console.WriteLine("NBA球员可以扣篮");
          }
      }
      
      class Person
      {
          public void CHLSS()
          {
              Console.WriteLine("人类可以吃喝拉撒睡");
          }
      }
      
      //实现多态
      IKouLan kl = new Driver();//new Teacher();//new Student();
      kl.KouLan();
      Console.ReadKey();

      经验:抽象类也可以继承接口,只要继承接口的都必要实现接口,所以抽象类也要实现接口。尽量不要出现这种情况让抽象类去实现接口,接口代表能力,子类有能力就实现接口,没能力就不去实现接口,如果都需要,那就直接写到父类中,不需要写到接口中让抽象类去实现。

【参考:https://www.jb51.net/article/128815.htm】

【参考:https://www.cnblogs.com/hxfcodelife/p/10384841.html】

原文地址:https://www.cnblogs.com/wangtao1211/p/12482675.html