zoukankan      html  css  js  c++  java
  • 面向对象三大特性之多态

    多态是什么?

        用一句话来概括下,多态就是同一操作(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果。这句话看似简

        单,实则颇有深意。下面我们来深入理解一多态的意义及如何使用多态。

    使用多态编程的好处

        在使用继承编程的时候,我们一般是把不同子类的方法分别写在不同的子类中,使用的时候用is a关键字来判断对象是哪种类型

        的,然后进行强制转换来使用不同对象的方法。

          但是,如果有多个子类的话,使用的时候难道要写多个if语句来判断对象是哪种类型的吗?这样会产生很多冗余代码,也会很繁

        琐。

        使用多态编程可以很好的解决这个问题。在父类写一个虚方法或抽象方法,子类去重写父类的方法,在调用的时候系统会根据对

        象运行时的类型决定调用哪个方法。这样子是不是简洁多了?

    小例子

        假设我们有一个“书”类,然后有很多子类继承“书”类。例如“计算机组成原理”类继承“书类”,“深入Java面向对象”继承“书”类...

        而这些子类都有类似的方法,即被不同的人使用。

        下面我们来用代码实现它。

     1 /// <summary>
     2     /// 演示类
     3     /// </summary>
     4     class Demo
     5     {
     6         List<Book> books = new List<Book>();
     7 
     8         /// <summary>
     9         /// 测试
    10         /// </summary>
    11         public void Test()
    12         {
    13             books.Add(new ComputerBook());
    14             books.Add(new JavaBook());
    15 
    16             foreach (Book item in books)
    17             {
    18                 if (item is ComputerBook)
    19                 {
    20                     ((ComputerBook)item).ByReading();
    21                 }
    22                 if (item is JavaBook)
    23                 {
    24                     ((JavaBook)item).ByReading();
    25                 }
    26             }
    27         }
    28     }
    29 
    30     /// <summary>
    31     /// 书类
    32     /// </summary>
    33     class Book
    34     {
    35         
    36     }
    37 
    38     /// <summary>
    39     /// 计算机书籍
    40     /// </summary>
    41     class ComputerBook : Book
    42     {
    43         /// <summary>
    44         /// 被阅读
    45         /// </summary>
    46         public void ByReading()
    47         {
    48             Console.WriteLine("我是计算机类书籍,被在校大学生使用。");
    49         }
    50     }
    51 
    52     /// <summary>
    53     /// Java书籍
    54     /// </summary>
    55     class JavaBook : Book
    56     {
    57         /// <summary>
    58         /// 被阅读
    59         /// </summary>
    60         public void ByReading()
    61         {
    62             Console.WriteLine("我是Java书籍,被在业Java程序员使用。");
    63         }
    64     }

         

         通过这段代码可以发现:在使用子类对象的时候需要先用is a来判断子类对象时哪种类型的。那么也就是说,如果一个父类有10

         个派生类(子类)的话,就要用10个if判断语句来判断子类对象是哪种类型了,未免太过繁琐。

         这时,虚方法就该登场了。

    虚方法

         概念:

            虚方法有方法体,可以被重写,使用virtual来修饰。

            父类中的虚方法并非必须被子类重写,在父类中可以给出虚方法的默认实现。如果子类不重写父类的虚方法则依然执行

            父类的默认实现。如果子类重写了父类的虚方法,则执行子类重写后的方法。

            其实方法重载也是实现多态的一种形式,只是重载的方法都在同一个类中,而用虚方法实现多态的方法散布在有继承关

            系的多个类中。

        使用:

            在父类中使用virtual关键字定义虚方法,在子类中使用override关键字来重写父类中的虚方法。

        override关键字:

            通过override关键字来修饰的方法,称为方法的重写。

        下面我们用虚方法来改造一下上面的例子

     1     /// <summary>
     2     /// 演示类
     3     /// </summary>
     4     class Demo
     5     {
     6         List<Book> books = new List<Book>();
     7 
     8         /// <summary>
     9         /// 测试
    10         /// </summary>
    11         public void Test()
    12         {
    13             books.Add(new ComputerBook());
    14             books.Add(new JavaBook());
    15             //遍历时不用加判断
    16             foreach (Book item in books)
    17             {
    18                 item.ByReading();
    19             }
    20         }
    21     }
    22 
    23     /// <summary>
    24     /// 书类
    25     /// </summary>
    26     class Book
    27     {
    28         public virtual void ByReading()
    29         {
    30 
    31         }
    32     }
    33 
    34     /// <summary>
    35     /// 计算机书籍
    36     /// </summary>
    37     class ComputerBook : Book
    38     {
    39         /// <summary>
    40         /// 被阅读
    41         /// </summary>
    42         public override void ByReading()
    43         {
    44             Console.WriteLine("我是计算机类书籍,被在校大学生使用。");
    45         }
    46     }
    47 
    48     /// <summary>
    49     /// Java书籍
    50     /// </summary>
    51     class JavaBook : Book
    52     {
    53         /// <summary>
    54         /// 被阅读
    55         /// </summary>
    56         public override void ByReading()
    57         {
    58             Console.WriteLine("我是Java书籍,被在业Java程序员使用。");
    59         }
    60     }

        

        可以看出,使用虚方法来写代码简便了许多。但是问题又来了,一般子类的父类和在父类中的虚方法是“宏观”的,“抽象”的,我

        们不想让这个父类被实例化并且只提供方法的定义,由子类去实现这个方法,该怎么做呢?

        如何解决这个问题呢?我们可以使用抽象类和抽象方法来实现。

    抽象类和抽象方法

        abstract关键字:

            abstract关键字用来修饰抽象类和抽象方法。

        抽象类:

            使用abstract关键字修饰的抽象类不能被实例化。

            抽象类中可以有非抽象方法。

            抽象类不能是密封的或者静态的。

        抽象方法:

            使用abstract关键字修饰的抽象方法是一个没有实现的方法,由子类重写抽象方法来实现。

            抽象方法没有大括号,直接在小括号后以分号";"结尾。

            含有抽象方法的类必须是抽象类。

            抽象方法必须在其子类中实现,除非它的子类也是抽象类。

        

        下面我们使用抽象类和抽象方法再次改造上面的例子

     1     /// <summary>
     2     /// 演示类
     3     /// </summary>
     4     class Demo
     5     {
     6         List<Book> books = new List<Book>();
     7 
     8         /// <summary>
     9         /// 测试
    10         /// </summary>
    11         public void Test()
    12         {
    13             books.Add(new ComputerBook());
    14             books.Add(new JavaBook());
    15             //遍历时不用加判断
    16             foreach (Book item in books)
    17             {
    18                 item.ByReading();
    19             }
    20         }
    21     }
    22 
    23     /// <summary>
    24     /// 书类
    25     /// </summary>
    26     abstract class Book
    27     {
    28         public abstract void ByReading();
    29     }
    30 
    31     /// <summary>
    32     /// 计算机书籍
    33     /// </summary>
    34     class ComputerBook : Book
    35     {
    36         /// <summary>
    37         /// 被阅读
    38         /// </summary>
    39         public override void ByReading()
    40         {
    41             Console.WriteLine("我是计算机类书籍,被在校大学生使用。");
    42         }
    43     }
    44 
    45     /// <summary>
    46     /// Java书籍
    47     /// </summary>
    48     class JavaBook : Book
    49     {
    50         /// <summary>
    51         /// 被阅读
    52         /// </summary>
    53         public override void ByReading()
    54         {
    55             Console.WriteLine("我是Java书籍,被在业Java程序员使用。");
    56         }
    57     }

         

        

        到了这里,我们可以发现使用虚方法和抽象方法来编程(也就是多态)更符合面向对象编程的思想,并且可以大幅的提升代码的

        可读性和减少冗余的代码。

        用更少的代码实现相同的实现,这感觉,很爽的。

        

    欢迎提出意见或建议!!!
  • 相关阅读:
    Redis最佳实践:7个维度+43条使用规范,带你彻底玩转Redis | 附实践清单
    laravel生命周期
    日志写入
    商城表设计
    10个你不一定知道的PHP内置函数
    PHP函数详解:call_user_func()使用方法
    Dingo与JWT的使用
    商城-会员与用户的数据表设计
    MVVM模式
    vue面试题
  • 原文地址:https://www.cnblogs.com/gaofei-1/p/6435442.html
Copyright © 2011-2022 走看看