例程S 2 _ 11程序清单
program Project1;
{$APPTYPE CONSOLE}
下载
t y p e
THuman = class // 人类
procedure ShowInf;virtual;
e n d ;
TStudent = class(THuman) // 学生类
procedure ShowInf;override;
e n d ;
T Worker = class(THuman) // 工人类
procedure ShowInf;override;
e n d ;
procedure THuman.ShowInf;
b e g i n
Wr i t e l n ( '调用T H u m a n . S h o w I n f ' ) ;
e n d ;
procedure TStudent.ShowInf;
b e g i n
Wr i t e l n ( '调用T S t u d e n t . S h o w I n f ' ) ;
e n d ;
procedure TWo r k e r. S h o w I n f ;
b e g i n
Wr i t e l n ( '调用T Wo r k e r. S h o w I n f ' ) ;
e n d ;
v a r
H1: THuman; // 声明一个人类的变量
S1: TStudent; // 声明一个学生类的变量
b e g i n
H 1 : = T H u m a n . C r e a t e ;
H1.ShowInf; // 调用的是T H u m a n类的S h o w I n f
H 1 . D e s t r o y ;
H 1 : = T S t u d e n t . C r e a t e ;
H1.ShowInf; // 调用的是T S t u d e n t类的S h o w I n f
T Worker(H1).ShowInf; // 调用的是T S t u d e n t类的S h o w I n f
H 1 . D e s t r o y ;
H 1 : = T Wo r k e r. C r e a t e ;
H1.ShowInf; // 调用的是T Wo r k e r类的S h o w I n f
THuman(H1).ShowInf; // 调用的是T Wo r k e r类的S h o w I n f
H 1 . D e s t r o y ;
S 1 : = T S t u d e n t . C r e a t e ;
S1.ShowInf; // 调用的是T S t u d e n t类的S h o w I n f
T Worker(S1).ShowInf; // 调用的是T S t u d e n t类的S h o w I n f
S 1 . D e s t r o y ;
e n d .运行结果如下:
调用T H u m a n . S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T Wo r k e r. S h o w I n f
调用T Wo r k e r. S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T S t u d e n t . S h o w I n f
以上是一本书的例子,但看了几次都看不懂。
1、T Worker(H1).ShowInf中的T Worker(H1)是什么意思?
2、为什么调用的是:
调用T H u m a n . S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T Wo r k e r. S h o w I n f
调用T Wo r k e r. S h o w I n f
调用T S t u d e n t . S h o w I n f
调用T S t u d e n t . S h o w I n f
我知道这个是多态性,一个新定义的方法只有在定义为virtual或dynamic, 子类才可以使用Override继承,以实现多态。但还是不知道为什么这样调用。

解决方案 »

  1.   

    基类中实现了一些基础功能,如果在子类中增强或代替某个函数的功能,就能过继承来实现父类中使用了virtual,子类就可以继承
    父类中使用了virtual和dynamic,子类就必须继承,因为父类没有实现它!
      

  2.   

    多態:
    Parent := Child;TParent = Class(TObject)
      procedure Draw;virtual;
    end;TChild = Class(TParent)
      procedure Draw;override;
      procedure ShowHierarchy;virtual;
    end;Child:=Parent;//這樣是不安全的
    如果這樣做;下面的代碼將是災難:
    Child.ShowHierarchy;Parent:=Child;//父對象設為等於子對象是沒問題的//這是就是,TParent的所有函數都是TChild的一部份;
    再說過例子:
    你可以用三層樓準備的材料來建築兩層樓;
    但是不能用兩層樓準備的材料來建築三層樓.
      

  3.   

    父类中使用了virtual和dynamic,子类可以继承,但不是必须继承!
    而抽象的是必须继承!因为使用抽象方法的类是抽象类,不能建立对象!
      

  4.   

    大虾挥了挥她的手,“冷静,小菜鸟,我不是指先知Coplien的那本书,我是指某种结构背后隐含的惯用法。比如一个类有virtual destructor,相当于告诉你说:‘嗨,我是一个多态基类,来继承我吧!’ 而如果一个类的destructor不是虚拟的,则相当于是在说:‘我不能作为多态基类,看在老天的份上,别继承我。’”“同样的,virtual函数的访问控制级别也具有隐含的意义。一个protected virtual function告诉你:‘你写的派生类应该,哦,可是说是必须调用我的实现。’而一个private virtual function是在说:‘派生类可以覆盖,也可以不覆盖我,随你的便。但是你不可以调用我的实现。’”我点点头,告诉她我懂了,然后追问道:“那么public virtual function呢?”“尽可能不要使用public virtual function。”她拿起一支笔写下了以下代码:class HardToExtend 
    {
    public:
     virtual void f();
    };
     void HardToExtend::f() 

    // Perform a specific action 
    }
    “假设你发布了这个类。在写第二版时,需求有所变化,你必须改用Template Method。可是这根本不可能,你知道为什么?”“呃,这个...,不知道。”“由两种可能的办法。其一,将f()的实现代码转移到一个新的函数中,然后将f()本身设为non-virtual的:class HardToExtend
    {
    // possibly protected
        virtual void do_f();
    public:
        void f();
    };
    void HardToExtend::f()
    {
        // pre-processing
        do_f();
        // post-processing
    }
    void HardToExtend::do_f()
    {
        // Perform a specific action
    }然而你原来写的派生类都是企图override函数f()而不是do_f()的,你必须改变所有的派生类实现,只要你错过了一个类,你的类层次就会染上先知Meyers所说的‘精神分裂的行径’。” [译者注:参见Scott Meyers,Effective C++, Item 37,绝对不要重新定义继承而来的非虚拟函数]“另一种办法是将f()移到private区域,引入一个新的non-virtual函数:”class HardToExtend
    {
    // possibly protected
        virtual void f();
    public:
        void call_f();
    };
    “这会导致无数令人头痛的问题。首先,所有的客户都企图调用f()而不是call_f(),现在它们的代码都不能编译了。更有甚者,大部分派生类都回把f()放在public区域中,这样直接使用派生类的用户可以访问到你本来想保护的细节。”“对待虚函数要象对待数据成员一样,把它们设为private的,直到设计上要求使用更宽松的访问控制再来调整。要知道由private入public易,由public入private难啊!”[译者注:这篇文章所表达的思想具有一定的颠覆性,因为我们太容易在基类中设置public virtual function了,Java中甚至专门为这种做法建立了interface机制,现在竟然说这不好!一时间真是接受不了。但是仔细体会作者的意思,他并不是一般地反对public virtual function,只是在template method大背景下给出上述原则。虽然这个原则在一般的设计中也是值得考虑的,但是主要的应用领域还是在template method模式中。当然,template method是一种非常有用和常用的模式,因此也决定了本文提出的原则具有广泛的意义。](转自超级猛料)
    看看会有收获的!