关于inherited (50分)

  • 主题发起人 主题发起人 kenmen
  • 开始时间 开始时间
K

kenmen

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个新类:
type
TCountButton = class (TButton)
constructor Create (AOwner: TComponent)
override;
destructor Destroy
override;
class function GetTotal: Integer;
end;

constructor TCountButton.Create (AOwner: TComponent);
begin
1)inherited;
Inc (TotBtns);
end;

destructor TCountButton.Destroy;
begin
Dec (TotBtns);
2)inherited Destroy;
end;
1)和2)中的inherited有啥用途?为啥2)之后有Destroy,而1)后是空的,没Create?
还有想问问class function GetTotal: Integer;这个类方法与普通类的方法有啥不同,
有啥用?在此先谢谢了!
 
继承啊,在creat 里面,如果没有1)那这个过程就之执行一个语句:inc(TotBtns);
而事实上,还应该进行创建,即分配内存,此时inherited 就调用了 TCountButton 的
父类的create进行内存分配
建议多看一看书 :-p
 
inherited是继承祖先类的方法,其实就是执行祖先类的同名方法(我是这么理解的)
下面是help的解释
The reserved word inherited plays a special role in implementing polymorphic behavior. It can occur in method definitions, with or without an identifier after it.
If inherited is followed by a method identifier, it represents a normal method call, except that the search for the method begins with the immediate ancestor of the enclosing method抯 class. For example, when

inherited Create(...);

occurs in the definition of a method, it calls the inherited Create.
When inherited has no identifier after it, it refers to the inherited method with the same name as the enclosing method. In this case, inherited can appear with or without parameters
if no parameters are specified, it passes to the inherited method the same parameters with which the enclosing method was called. For example,

inherited;

occurs frequently in the implementation of constructors. It calls the inherited constructor with the same parameters that were passed to the descendant.
 
beta说得没错,
另外,1)处:
inherited;

inherited Create(nil);
的效果完全相同。

class function GetTotal: Integer;是个类方法,可用来访问已定义的类型信息的。
而不带Class关键字的方法是对象方法,是用来访问对象的。
找一本Object Pascal的书来好好看一看嘛。
 
先谢谢各位了!我是有看书的,只是不大明。
各位好心人能再说详细点吗?
 
在Create中的inherited相当于:
constructor TCountButton.Create (AOwner: TComponent);
begin
inherited Create(AOwner)
//调用TButton的Create
Inc (TotBtns);
end;

destructor TCountButton.Destroy;
begin
Dec (TotBtns);
inherited Destroy
//调用TButton的Destroy
end;

class function 与正常function的区别在于, 在类还没有创建的时候就可以调用, 正常的
function只能在一个对象被创建了之后才能使用.

例如:
首先, 建立一个新Application, 在Form1上加上两个按钮 btnCreate and btnGetCount再放
一个Label用来显示Total CountButton. 他们都放在Form的上部 < 30 的区域. 全部代码如下:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TCountButton = class (TButton)
public
constructor Create (AOwner: TComponent)
override;
destructor Destroy
override;
class function GetTotal: Integer;
end;

TCountButtonClass = class of TCountButton;
TForm1 = class(TForm)
btnCreate: TButton;
Label1: TLabel;
btnGetCount: TButton;
procedure btnCreateClick(Sender: TObject);
procedure btnGetCountClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

const
TotBtns: integer = 0;
{ TCountButton }

constructor TCountButton.Create(AOwner: TComponent);
begin
inherited;
inc(TotBtns);
end;

destructor TCountButton.Destroy;
begin
Dec(TotBtns);
inherited;
end;

class function TCountButton.GetTotal: Integer;
begin
result := TotBtns;
end;

procedure TForm1.btnCreateClick(Sender: TObject);
var
btn: TCountButton;
begin
btn := TCountButton.Create(self);
btn.Left := 10;
btn.Top := btn.GetTotal * 30;
btn.Parent := self;
end;

procedure TForm1.btnGetCountClick(Sender: TObject);
var
btn: TCountButton;
begin
label1.Caption := IntToStr(btn.getTotal);
//注意: 此处我们并没有被Create btn这个Object, 如果getTotal不是Class function这样
//使用是非法的
end;

end.
 
再讲多了也是抄书本,你到底是哪不明白?
 
说简单点, TCountButton 继承于 TButton
inherited func 就相当于 TButton.func
inherited Create(...) 就相当于 TButton.Create(...)
 
我还想问问,1)中的creat有哪些参数,是否如douh所说的跟nil,还有其他吗?
还有,有两个定义:
procedure TForm1.ButtonKeyPress(Sender: TObject;
var Key: Char);
begin
if Key = #8 then
sender.free;
end;

procedure TForm1.ButtonKeyPress(Sender: TObject;
var Key: Char);
begin
// if user pressed backspace
if Key = #8 then
// set this as the object to destroy
3)ToDestroy := Sender as TButton;
end;
为啥第一个错了,第二个对?
3)这句是怎用法的?Sender as TButton 的意思是把TButton 作为Sender吗?
as的用法就是这样吗?
我知道我的问题是长了点,请原谅。还有。。。。。请指教!
 
1)create的参数由祖先类确定
2)sender as tbutton 就是把sender强行赋为tbutton类,就是用过这句后,sender的类型就变为tbutton
使用方法:
A as B 中一般A必须为B的祖先类
 
1、这里的AOwner是一个对象指针而已,用来表要创建的对象的拥有者,可以传回一个
空指针就是nil,也可以传回一个指向一个对象实例的指针,但应当是TObject和它的子
类对象,比如常用的将当前对象的Self传给新建对象,但据我的经验,很多情况下这样
没有实际意义,只对一部份子类才是有用的,如:新建的子类是TREEVIEW及LISTVIEW的
节点对象、集合的成员等等,这是要把其所属的容器类对象指针(当前时为Self)传给
子类的Create函数。
2、Sender也是对象指针,但意义不同,它是指向发生该动作事件的对象。比如是用户
点击了一个菜单项或一个按钮,那么事件处理里传来的Sender就指向这个菜单项或按钮
对象。这些对象一定不是TObject类,但一定是TObject的子类,所以要对Sender操作就
一定要对Sender进行TypeCast(强行类型转换)。你的第一个例子中没有TypeCast,实
际上是调用了TObject的Free方法,而它的子类往往(这里是一定的)对Free方法进行
了不少修改,这样释放对象会造成内存泄漏,
3、As的用法是:<object> AS <class>返回一个对象指针(object),含义与你说的相
反:是将object做为class类型的对象来处理,在这里就是将Sender做为TButton 类型
的对象来处理,ToDestory就得到了一个TButton的对象。
说了这么多不知能满意否?
 
更正:一发送怎么就掉东西?
3、As的用法是:<object>AS<class> 返回一个对象指针(object),含义与你说的相
反:是将object做为class类型的对象来处理,在这里就是将Sender做为TButton 类型
的对象来处理,ToDestory就得到了一个TButton的对象。
说了这么多不知能满意否?
 
靠!这是HTML!
AS的用法:object AS class
 
说继承的正确,delphi封装了windows的消息循环,delphi的所有组件都继承自TObject类
inherited是使当前组件不处理的一些消息,向类继承层次中的上一级传递,并最终实现消
息被父类默认处理。好了,发分吧。
 
我想再问问,到底free和destroy有啥不同?
我看有些程序一开始就create,而有些却没有?为啥呢?
 
自己不认真思考,讲太多也没有用
 
我有想的,只是想不明,请各位高手指点指点!
 
:)))楼上的各位讲的够清楚了
free和destroy的区别在于: destroy直接释放(有时因此而产生错误, 因为可能已为nil),
free先是判断是否为nil, 如果不是则调用destroy释放
 
问题:我看有些程序一开始就create,而有些却没有?为啥呢?
回答:对于VCL,如果是存在于DFM中,就由DELPHI编译器自动生Create的目标码(实际上,
这些"不用创建"的类是由一个叫TReader的类从流中读出后创建的。而TFORM类的对象本身
是在DPR文件中创建的。
 
哪什么时候需要自己create呢?
 
后退
顶部