zoukankan      html  css  js  c++  java
  • 我学Delphi心得及笔记面向对象系列(多态)

    多态

    1什么是多态?

    1.1概念

    多态的概念众说纷纭,下面是几种代表性的说法:

    This ability to manipulate more than one type with a pointer or a reference to a base classis spoken of as polymorphism (C++ Primer》第838)。即用基类的指针/引用来操作多种类(基类和其派生类)的对象的能力称之为多态。它是从语言实现的角度来考虑的。

    polymorphism provides another dimension of separation of interface from implementation, to decouple what from how(Think in Java3rd edtion),即多态提供了另外一种分离接口和实现(即把“做什么”与“怎么做”分开)的一种尺度。它是从设计的角度考虑的。

    The ability to use the same expression to denote different operations is refered to as Polymorphism”,(Object-Oriented Methods Principles & Practice3rd Edition,第16)。简单的说,多态就是“相同的表达式,不同的操作”,也可以说成“相同的命令,不同的操作”。这是从面向对象的语义的角度来看的。

    三种说法分别从不同的角度来阐述了多态的实质。其中第三种说法尤为确切,下面着重分析第三种说法。

    先解释这句话的含义:

    相同的表达式—函数调用

    不同的操作  —根据不同的对象就有不同的操作。

    举个例子来说明,比如在公司中有各种职责不同的员工(程序员,业务员,文管等),他们“上班”时,做不同的事情(也可以看作是一种业务逻辑),我们把他们各自的工作都抽象为"上班",关系如下:

                          员工

                        /   |   \     ——继承关系

                  程序员业务员文管

    每天上班时间一到,相当于发了一条这样的命令:

      “员工们.开始上班”(同一条表达式)

    每个员工接到这条命令(同样的命令)后,就“开始上班”,但是他们做的是各自的工作,程序员就开始“Coding”,业务员就开始“联系业务”,文管员就开始“整理文档”。即“相同的表达式(函数调用)(在运行期根据不同的对象来执行)不同的操作

    下面我们来用Delphi实现这个实例

    View Code
    Type
    Employee
    =Class(Tobject)//员工基类
    public
    procedure Work;Virtual;abstract;//开始工作的过程
    end;
    Programmor
    =Class(Employee)//程序员类--继承自员工类
    public
    procedure Work;override;//程序员的工作过程
    end;
    BusinessMan
    =Class(Employee)//业务员类--继承自员工类
    public
    procedure Work;override;//业务员的工作过程
    end;
    DocManager
    =Class(Employee)//文档管理员类-----继承自员工类
    public
    procedure Work;override;//文档管理员的工作过程
    end;

    procedure Programmor.Work;//程序员的具体工作过程实现
    begin
    Showmessage(
    '程序开始Coding');
    end;

    procedure BusinessMan.Work;//业务员的具体工作过程实现
    begin
    Showmessage(
    '业务员开始联系业务');
    end;
    procedure DocManager.Work;//文档管理员的具体工作过程实现
    begin
    Showmessage(
    '文档管理员开始整理文档');
    end;

    //上班了,各位员工开始工作
    procedure TForm1.btn2Click(Sender: TObject);
    const
    Num
    =3;
    var
    emp:
    arrayof Employee;
    i:Integer;
    begin
     
    //实现多态
    setLength(emp,Num);
    emp[
    0]:=Programmor.Create;
    emp[
    1]:=BusinessMan.Create;
    emp[
    2]:=DocManager.Create;
    for i:=0to length(emp)-1do
    emp[i].Work;
    //分别调用各员工的具体的工作过程
    end;

    1.2多态的意义

    封装和继承的意义是它们实现了代码重用,而多态的意义在于,它实现了接口重用(同一的表达式),接口重用带来的好处是程序更易于扩展,代码重用更加方便,更具有灵活性,也就能真实地反映现实世界。

    比如为了更好地管理,把程序员分为C++程序员,Delphi程序员。…

                          员工

                        /   |   \      ——继承关系

                  程序员业务员文管

                   /   \               ——继承关系

          C++程序员  Delphi程序员

    代码如下:

    
    
    View Code
    Type
    CppProgarmmer
    =class(Progarmmer)//c++程序员,继承自程序员类
    public
    procedure Work;override;//c++程序员的工作过程
    end;
    DelphiProgarmmer
    =class(Progarmmer)//delphi程序员,继承自程序员类
    public
    procedure Work;override;//delphi程序员的工作过程
    end;

    procedure CppProgarmmer.Work;
    begin
    Showmessage(
    'C++ 程序员开始高度Bug!');
    end;
    procedure DelphiProgarmmer.Work;
    begin
    Showmessage(
    'Delphi 程序员开始Coding!');
    end;
    //现在重新调用
    //上班了,各位员工开始工作
    procedure TForm1.btn2Click(Sender: TObject);
    const
    Num
    =5;
    var
    emp:
    arrayof Employee;
    i:Integer;
    begin
     
    //实现多态
    setLength(emp,Num);
    emp[
    0]:=Programmor.Create;
    emp[
    1]:=BusinessMan.Create;
    emp[
    2]:=DocManager.Create;
    emp[
    3]:=CppProgarmmer.Create;
    emp[
    4]:=DelphiProgarmmer.Create;
    for i:=0to length(emp)-1do
    emp[i].Work;
    //分别调用各员工的具体的工作过程
    end;
    
    
    
    
    

    多态的实质是:相同的表达式,不同的操作(就这么简单),

    OOP语言的实现来讲,多态就是使用基类的指针/引用来操作(派生类)对象,在运行期根据实际的对象,来执行不同的操作方法;

    或者换一种更形象的说法:由对象自己来决定自己操作方式,编译器只需下达做什么的命令(做什么what),而不要管怎么做(how),"怎么做"由为对象自己负责。

    这样就实现了接口和实现的分离,使接口重用变得可能

    其实多态也简单!那么使用多态应该注意什么呢?下面是一些建议:

    分析业务逻辑,然后把相关的事物抽象为“对象”,再用对象方法封装业务逻辑。把一些具有多态性的操作,在基类中声明为虚方法(virtual Method)

    对于在基类没有必要实现的就声明为抽象方法(virtual Abstract Method),然后在其派生类中再覆载它(Override),在使用的时候用基类的引用/指针来调用,

    这样顺理成章地实现了现实世界中的多态性。记住千万不要为了多态,而去实现多态,这是一种走形式化的做法,是没有意义的。

    由于基类与派生类有一种天然“耦合”关系,修改基类就会导致“牵一发而动全身”,这将是非常麻烦的事情!因此要尽量弱化基类的功能实现,

    必要时把它设计为“抽象类”,并保证稳定的接口,这可以通过预留一些冗余的虚函数(或抽象函数)来实现

  • 相关阅读:
    网恋现代人的童话
    男人爱女人
    在Web页面中管理服务
    wcf使用入门学习笔记
    table显示细线边框
    wcf整理资料
    启动sqlserver服务的时候报错
    命名规范
    .net中使用xsl文件作为导航菜单
    wcf如何选择绑定
  • 原文地址:https://www.cnblogs.com/youshan/p/2118700.html
Copyright © 2011-2022 走看看