zoukankan      html  css  js  c++  java
  • 面向对象的多态性

    面向对象的软件开发语言具有三个重要的特点分别为封装性、继承性、多态性。封装性即意味着对象封装其内部的数据,使其对外不可见,以保证数据的安全性。继承性是代码复用的一个很好的解决方案,但是继承关系是编译器在编译阶段就为所有的对象决定的,因而在软件工程过程中,继承性太过死板,存在很大的局限性。而多态性,它是将多种不同的特殊行为进行抽象的一种能力,通过结合继承性,多态性很好地解决了OO遇到的很多麻烦,使得面向对象的编程方式最终得到淋漓尽致的推广。

     

    多态性和泛型编程

    各种编程语言都内置了多种基本数据结构并且支持自定义数据类型,因而程序员在程序设计过程中可能会遇到多种数据类型,而针对这些数据类型的逻辑操作很有可能是雷同的。此时为每一种数据类型都设计出相应的逻辑函数似乎已经变得很不现实,因而泛型编程孕育而生了。泛型编程的出现,可以说在软件工程领域里是一个极大的进步。利用泛型编程,我们可以不为特定的类型进行专门编码,而采用对不同类型进行通用编码的方式来解决应对大量数据类型的问题。C++ STL是泛型编程的成功案例。利用Template函数,STL成功实现了对多种数据类型进行泛化的效果。而OO通过接口或者抽象类进一步实现了对类的泛化,也就是在面向对象过程中出现的新名词多态!

     

    多态性特点

    简单来说,多态是具有表现多种形态的能力的特征,在OO中是指,语言具有根据对象的类型以不同方式处理,即指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象。多态性在不同的编程语言中拥有不同的解决方案,但多态性的最终目标却始终不变,都是“以不变应万变”。

     

    两种多态方式

    一般来说,多态主要是存在两种类型:编译时的多态和运行时的多态。

    编译时的多态主要是通过函数重载来实现的。所谓函数重载是指保持函数名不变,主要通过更改函数形参的个数以及形参的类型来定义出多个同名函数来实现对多种类型数据的逻辑处理。这种类型的多态关系是编译器在编译阶段就已经在函数调用的地方确定的,因而运行过程中速度较快,但功能比较局限。

    运行时的多态在不同的语言中拥有不同的实现方案。C++通过虚函数的晚捆绑来实现,而Java通过面向接口编程和面向抽象编程来实现动态调用相应的函数实现。但归根结点,这些语言都是通过将多种特殊实现的类抽象为一个泛化类来实现运行多态。

     

    面向接口编程

       软件工程中程序涉及到的对象越多,对象之间相似的概率越大,因而这时候抽象变成了可能。通过定义接口,程序设计者可以成功实现对方法的定义和实现的分离,因而应用程序不必考虑子类成员函数中是如何实现内部逻辑细节,只需知道该类对象向外公开的接口便可成功操纵这类对象。而这种编程方式,为以后程序的改动以及程序的健壮性和扩展性都提供了一个比较理想的解决方案。因此面向抽象编程已经成为OO界强烈推崇的编程方式。

     

    OO思想已经深入广大编程人员的工作中,如何能够充分合理利用OO的特点达到最优化软件体系结构将会成为每一个OO程序员应该思考的问题,相信OO思想能够为大家的软件设计带来前所未有的效果。

    多态是指两个或多个属于不同类的对象,对于同一个消息(方法调用)作出不同响应的方式。实现多态的方式:

    一、抽象类和抽象方法

        1、 抽象类的语法:

                             访问修饰符 abstrac class 类名

        2、 父类中的方法:

                             访问修饰符 abstrac 返回类型 方法();

    注意:含有抽象方法的类必然是抽象类。抽象类中的方法并不一定都是抽象方法。

             抽象类是不能被实例化的。只能通过它的子类来实现该类的方法,除非它的子类也是一个抽象类。

             抽象类不能是密封或者静态的,抽象类被子类继承并实现它的抽象方法。

        3、重写抽象方法:

                              访问修饰符 override 返回类型 方法()

         4、使用场合:

                           A 父类提供了一个功能或者规定,约束子类的行为。

     示例:


    abstract public class Person
        
    {
            
    abstract public void SayHi();
        }


    //子类
       public class Student:Person
        
    {
          
    public override void SayHi()
            

                 
    //代码省略
            }

         }


        
    public class Teacher:Person
        
    {
          
    public override void SayHi()
            

                 
    //代码省略
             }

         }

    里氏替换原则

         "is"操作符用于检查对象是否与给定的类型相同。如: if(obj is string){}

         "as"用于两个对象之间的类型转换。如:string as obj;

    注意:as运算符当转换失败时,运算符将产生空,而不是引发异常。

            is转换失败要发生异常。

    二、虚方法:

                    访问修饰符 virtual 返回类型 方法()

                   {

                         //方法体

                   }

     1、每个对象Object都有一个Equals()方法,用于确定两个实例对象是否相等,它是一个虚方法,可以重写这个方法。

          public virtual bool Equals(Object obj)

          默认情况下,Equals()方法只支持引用相等,也就是相比较的两个对象是否引用同一个对象。

          重写Equals()虚方法如:


            public override bool Equals(object obj)
            
    {
                
    //将要比较的对象转换为当前类型
                Student target = obj as Student;

                
    //如果为空、类型不同
                if (target == null)
                    
    return false;

                
    if (target.name == this.name &&
                    target.gender 
    == this.gender &&
                    target.age 
    == this.age &&
                    target.hobby 
    == this.hobby &&
                    target.popularity 
    == this.popularity)
                
    {
                    
    return true;
                }

                
    return false;
            }

    2、虚方法和抽象方法的区别:

      A、修饰的关键字不同

      B、父类中方法体的区别

      C、重写的区别(抽象方法必须override)

      D、抽象方法只能在抽象类中,而虚方法除了密封类外都可以写

    3、方法重写的条件:

         A、方法签名必须一样

         B、访问修饰符允许被放大

         C、返回类型必须一样   

    总结:面向对象的三大特征

            封装:保证对象自身数据的完整性、安全性

            继承:建立类之间的关系,实现代码复用、方便系统的扩展

            多态:相同的方法调用可实现不同的实现方式

    三、方法重载

          1、与重写方法的区别

               A、应用场合不同:如果父类中有abstract/virtual,才能被重写,重写方法要求类与类之间是继承关系。

                                        而重载没有过多的要求。

    四、方法隐藏:父类和子类的方法都存在。

    五、静态(satice)类/密封(sealed)类/抽象(abstract)类它们各自的特点:

    深入.Net平台和C#编程

    主要记录的是学习笔记,以及在编程过程中应该注意的问题。

    摘要: 一、抽象类和抽象方法: 二、虚方法:虚方法和抽象方法的区别 方法重写的条件 三、方法重载 四、方法隐藏阅读全文

    posted @ 2009-06-06 01:09 记录 阅读(1094) | 评论 (0) 编辑 |

    摘要: 继承的概念,继承的特征,编写子类构造函数注意事项。阅读全文

    posted @ 2009-06-05 14:32 记录 阅读(94) | 评论 (0) 编辑 |

    摘要: 一、如何读写文件: 二、File类的方法: 三、Directory类的方法: 四、XML的解析:阅读全文

    posted @ 2009-06-05 12:03 记录 阅读(124) | 评论 (0) 编辑 |

    摘要: 一、泛型集合List: 二、泛型集合Dictionary: 阅读全文

    posted @ 2009-06-03 14:39 记录 阅读(237) | 评论 (1) 编辑 |

    摘要: 介绍:常量、枚举、结构与类的区别、索引器的使用阅读全文

    posted @ 2009-06-03 13:23 记录 阅读(144) | 评论 (0) 编辑 |

    摘要: 介绍:一、类的成员;二、类和对象的关系;三、类和对象的使用;四、封装的好处;五、在类中使用方法:六、方法的重载: 七、静态方法和实例方法的区别:八、使用构造函数创建对象:阅读全文

    posted @ 2009-06-02 19:25 记录 阅读(790) | 评论 (0) 编辑 |

    摘要: 自定义的命名空间需注意:阅读全文

    posted @ 2009-06-02 14:29 记录 阅读(189) | 评论 (0) 编辑 |

    摘要: .Net框架具有两个主要组件,.NET的编译原理阅读全文

    posted @ 2009-06-02 13:36 记录 阅读(451) | 评论 (0) 编辑 |

  • 相关阅读:
    Android Things专题 1.前世今生
    用Power BI解读幸福星球指数
    [leetcode]Simplify Path
    字段的划分完整的问题
    k-means算法MATLAB和opencv代码
    【Oracle】RAC下的一些经常使用命令(一)
    Java中经常使用缓存Cache机制的实现
    jenkins环境自动部署
    jenkins环境搭建
    springboot单元测试@test的使用
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2425387.html
Copyright © 2011-2022 走看看