例程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继承,以实现多态。但还是不知道为什么这样调用。
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继承,以实现多态。但还是不知道为什么这样调用。
父类中使用了virtual和dynamic,子类就必须继承,因为父类没有实现它!
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的一部份;
再說過例子:
你可以用三層樓準備的材料來建築兩層樓;
但是不能用兩層樓準備的材料來建築三層樓.
而抽象的是必须继承!因为使用抽象方法的类是抽象类,不能建立对象!
{
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是一种非常有用和常用的模式,因此也决定了本文提出的原则具有广泛的意义。](转自超级猛料)
看看会有收获的!