program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils;type
  Thuman=class
    public
         procedure ShowInf;virtual;
  end;  TStudent=class (THuman)
    public
    procedure ShowInf;override;
  end;  TWorker=class (THuman)
    public
     procedure ShowInf;override;
    end;    procedure Thuman.ShowInf;
    begin
      Writeln('调用Thuman.ShowInf');
    end;    procedure TStudent.ShowInf;    begin
     Writeln('调用TStudent.ShowInf');
    end;    procedure TWorker.ShowInf;
    begin
     Writeln('调用TWorker.ShowInf');
    end; var
 S1:TStudent;
 W1:TWorker;
 H1:THuman;begin
H1:=THuman.Create;
H1.ShowInf;
H1.Destroy;H1:=TStudent.Create;
H1.ShowInf;
TWorker(H1).ShowInf;  //这里问什么调用结果是:调用TStudent.ShowInf
H1.Destroy; //不是强制类型转换了吗?如果不是,那TWorker(H1)起什么作用?
            //是不是在创建的时候决定的?H1:=TWorker.Create;
H1.ShowInf;
THuman(H1).ShowInf;
H1.Destroy;S1:=TStudent.Create;
S1.ShowInf;
TWorker(S1).ShowInf;
S1.Destroy;
end.

解决方案 »

  1.   

    多态,TStudent是TWorker的子类。
      

  2.   

    是啊,这是个多态的问题,你的H1是一个指象Tstudent的对象,当然转成父类也还是调用TStudent的方法,TWorker(s1).showinf;只是个临时的转换
      

  3.   

    我和楼主一样,不知道类的强制类型转换都转换什么?是不是只扩充大小,如果格式小的话。而对dmt,vmt不做修改,不知道是不是这样的。希望有高手来解答
      

  4.   

    兄台可以在C++中试试。
    CWorker* pW = new CWorker();
    CHuman* pH = (CHuman*)pW;  //强制转换
    pW->showinf();好像调用的还是CWorder的函数吧。
    多态好像在C++中和Delphi中差不多吧。
      

  5.   

    刚刚看了钱能C++里的多态,我能理解:动态编联,
    但是这里:
    H1:=TStudent.Create;
    H1.ShowInf;
    TWorker(H1).ShowInf; 
    这个“TWorker(H1).ShowInf; ”是个什么含义阿??
    那位能说说???
    TWorker(H1)是什么意识
      

  6.   

    是不是这样理解:TWorker(H1)这个东西调用的时候,一般情况下时调用TWorker自己的东西,
    但是在H1这个参数(和前面虚函数的)的影响下,动态编联到H1这个变量所对应的类的操作了。
    而不是我先前考虑的“强制类型转换”。
    应该是这样理解把?
      

  7.   

    是不是这样理解:TWorker(H1)这个东西调用的时候,一般情况下时调用TWorker自己的东西,
    但是在H1这个参数(和前面虚函数的)的影响下,动态编联到H1这个变量所对应的类的操作了。
    而不是我先前考虑的“强制类型转换”。
    应该是这样理解把?
    // 
    type
      Thuman=class
        public
             procedure ShowInf;virtual;
      end;
    //
    procedure ShowInf;virtual;
    会在运行期确定调用那个子类的ShowInf
      

  8.   

    虚拟方法和动态方法不同于静态方法,它们可以在其后裔类中被覆盖(overridden)。当一个覆盖方法被调用时,方法调用中使用的类或对象的实际(运行时)类型决定了哪一个实现是有效的,而非变量声明的类型决定。
    ----------------------------------------------------------------------------------
    楼主请好好理解上面的话。
      

  9.   

    var
     S1:TStudent;
     W1:TWorker;
     H1:THuman;H1:=TStudent.Create;
    H1.ShowInf;
    TWorker(H1).ShowInf;  //这里问什么调用结果是:调用TStudent.ShowInf
    H1.Destroy; //不是强制类型转换了吗?如果不是,那TWorker(H1)起什么作用?
                //是不是在创建的时候决定的?我这么认为:虽然你声明的的是THUMAN 变量.后来也类型转换,但是实际上他是以TSTUDENT类创建的对象.实际上还是调用了TSTUDENT的方法.
    着就是多态性的问题.楼上的几位说的都有道理.
      

  10.   

    我的理解是:
    强制类型转换仅仅是方便你的临时操作,绝对不会真正改变数据结构。
    所以还是调用了TSTUDENT的方法.
    另外,是动态编联。
      

  11.   

    H1:=THuman.Create;//动态编联
    H1.ShowInf;
    H1.Destroy;H1:=TStudent.Create;//动态编联,已经确定了是TStudent,强制类型转换也没用了!
    H1.ShowInf;
    TWorker(H1).ShowInf; //强制类型转换 
    H1.Destroy;