看到小白同志说的那个动物类,让我想起一本书里的例子,于是还是想给兄弟再解释一次。 话说我们先声明一个父类(动物类),里面呢我们再声明一个玩的方法play(), TAnimal = class public procedure play(); end; 接着我们实现一下动物类的方法,我们假设动物们都喜欢躲猫猫吧。 procedure play(); begin {躲猫猫} end;
我们都知道,猫啊,狗啊,猪啊。都是属于动物类的。而且每种动物它都会有一个玩的方法,只不过每种动物玩的方法都不一样罢了,例如猫可能喜欢玩那些颜色花花绿绿的球,狗喜欢往地里埋骨头,而猪或许更多的比较喜欢睡觉。当然这都是举例子,关键是想说每种动物都必然会有一个玩的方法play(),而且一般来说都不一样,那么我们之前在动物类中实现的play()方法中说但凡动物的play方法都是躲猫猫,这很有可能引发一场动物抗议,原因刚刚有说到。 那么如何解决这样的问题呢?那好吧,我们给这个play方法设置一个标记(virtual)吧,通过这个标记,我们告诉所有的动物们(即动物类的子类,例如猫类,狗类等等),你们可以有自己专属的play方法,同时如果你也喜欢躲猫猫的话,那么就在你的play方法中写上一个inherited吧。当然你必须也给你的play方法打上一个标记(override)来告诉动物类(父类),你重写了动物类的play方法。 好的,我们再重新声明动物类,在play方法后面加上标记virtual。 TAnimal = class public procedure play(); virtual; end; procedure play(); begin {躲猫猫} end; 接着我们定义动物类的子类,一个猫类,一个狗类。
TCat = class(TAnimal) public procedure play; override; end;
procedure play(); begin {玩球} end; 这里我们用来新的玩球来实现play方法,而play方法后面我们也有做标记哦(override) TDog = class(TAnimal) public procedure play; override; end; procedure play(); begin inherited; end; 这里我们假设狗也喜欢玩躲猫猫这个游戏,那么这和它的父类(动物类)的play方法的实现是一样的,那么我们只需要继承一下父类当中的play就可以了。 打完这些字,我瘫了。不知道这解释算不算生动,够不够细致? 还是说依然让兄弟一头雾水?如果真是这样的话,我只能随风飘远了。 兄弟基础比我都差,买本书认真啃吧。
procedure One; override; 子类重载这个父类的方法,这里可以不执行父类代码,也可以inherited父类代码
你看看多态的知识吧
MyClass = class --父类MyClass
procedure One; virtual; --父类声明一个virtual方法,那么继承它的子类就必须重写该方法。
end;MySubClass = class (MyClass) --MyClass的子类MySubClass
procedure One; override; --override即重写。
end;非要说功能的话,
override是重写父类声明的虚方法(virtual).
而virtual是指让子类对该方法进行重写。
当然你应该经常看到除了override之外,还有一个overload(重载)。
overload不仅可以重载父类的方法,而且本类中的方法也可以重载。
那么什么是重载?打个比方,
procedure x(int a);
procedure x(float a);
procedure x(int a,int b);
你会发现上面三个过程的名称都是x,但是参数类型不一样,或者参数个数不一样,以上就是典型的重载。语言水平不高,讲得不好。
具体的动物类与动物类定义的走路方法实现相同时,直接继承就可以;如果不相同,那么可以覆盖动物类中的方法。TAnimal = class
public
procedure walk; virtual;
end;TBird = class(TAnimal)
public
procedure walk; override;
end;TFish = class(TAnimal)
public
procedure walk; override; //这个类中的walk,跟TAnimal类中的walk差别比较大,需要覆盖了。
end;TJapanese = class(TAnimal)
public
procedure walk; override;
end;
引用 5 楼
引用 6 楼
引用 7 楼[/Quote]的解释虽然很仔细。。 但我的脑还是有点纠结。。
关于 virtual method table (VMT, 也叫vtable)。
它藏在编辑器(Embarcadero RAD Studio 2010) 的哪里??
找不到的。。
那我不知道,反正delphi5里是在system单元的92行。
我想问的是,你看这个干嘛?如果你想知道virtual方法的话,不是看这个,还是看书,或者上网搜索。
这是我从DELPHI SYSTEM单元拷贝出来的
{ Virtual method table entries } vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32;
vmtAfterConstruction = -28;
vmtBeforeDestruction = -24;
vmtDispatch = -20;
vmtDefaultHandler = -16;
vmtNewInstance = -12;
vmtFreeInstance = -8;
vmtDestroy = -4; vmtQueryInterface = 0;
vmtAddRef = 4;
vmtRelease = 8;
vmtCreateObject = 12;
为什么找不到的??
我不是已经把那个什么VMT都给你拷贝出来了吗?就是那些内容啊。这些东西不过是偏移量罢了,用来确定方法指针地址的。{ Virtual method table entries } vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32;
vmtAfterConstruction = -28;
vmtBeforeDestruction = -24;
vmtDispatch = -20;
vmtDefaultHandler = -16;
vmtNewInstance = -12;
vmtFreeInstance = -8;
vmtDestroy = -4; vmtQueryInterface = 0;
vmtAddRef = 4;
vmtRelease = 8;
vmtCreateObject = 12;我不知道怎么回答了。闪人,这点分难拿。
话说我们先声明一个父类(动物类),里面呢我们再声明一个玩的方法play(),
TAnimal = class
public
procedure play();
end;
接着我们实现一下动物类的方法,我们假设动物们都喜欢躲猫猫吧。
procedure play();
begin
{躲猫猫}
end;
我们都知道,猫啊,狗啊,猪啊。都是属于动物类的。而且每种动物它都会有一个玩的方法,只不过每种动物玩的方法都不一样罢了,例如猫可能喜欢玩那些颜色花花绿绿的球,狗喜欢往地里埋骨头,而猪或许更多的比较喜欢睡觉。当然这都是举例子,关键是想说每种动物都必然会有一个玩的方法play(),而且一般来说都不一样,那么我们之前在动物类中实现的play()方法中说但凡动物的play方法都是躲猫猫,这很有可能引发一场动物抗议,原因刚刚有说到。
那么如何解决这样的问题呢?那好吧,我们给这个play方法设置一个标记(virtual)吧,通过这个标记,我们告诉所有的动物们(即动物类的子类,例如猫类,狗类等等),你们可以有自己专属的play方法,同时如果你也喜欢躲猫猫的话,那么就在你的play方法中写上一个inherited吧。当然你必须也给你的play方法打上一个标记(override)来告诉动物类(父类),你重写了动物类的play方法。
好的,我们再重新声明动物类,在play方法后面加上标记virtual。
TAnimal = class
public
procedure play(); virtual;
end; procedure play();
begin
{躲猫猫}
end;
接着我们定义动物类的子类,一个猫类,一个狗类。
TCat = class(TAnimal)
public
procedure play; override;
end;
procedure play();
begin
{玩球}
end;
这里我们用来新的玩球来实现play方法,而play方法后面我们也有做标记哦(override) TDog = class(TAnimal)
public
procedure play; override;
end; procedure play();
begin
inherited;
end;
这里我们假设狗也喜欢玩躲猫猫这个游戏,那么这和它的父类(动物类)的play方法的实现是一样的,那么我们只需要继承一下父类当中的play就可以了。
打完这些字,我瘫了。不知道这解释算不算生动,够不够细致?
还是说依然让兄弟一头雾水?如果真是这样的话,我只能随风飘远了。
兄弟基础比我都差,买本书认真啃吧。