delphi面向对象编程问题

salut 2010-01-08 04:47:40
我想学习面向对象编程,想做一个系统自带的“挖地雷”那个小游戏,我想把地雷定义一个类,我在单独的单元DiLei中这样定义:
unit Dilei;

interface
uses
Buttons;
type
TDiLei = class //地雷类别
private
{ Private declarations }
public
btn: TSpeedButton; {按钮}
btnLeft: Integer;{left}
btnTop: Integer;
btnWidth: Integer;
btnHeight: Integer;
constructor create(l,t: Integer);overload;
{ Public declarations }
end;

implementation



constructor TDiLei.create(l,t: Integer);
begin
Self.btn := TSpeedButton.Create(Self);
Self.btn.Width := 22;
Self.btn.Height := 22;
Self.btn.Left := l;
Self.btn.Top := t;
Self.btn.Show
end;

end.

//////////////////////////////////////////////////////////////////////////////////////
然后在窗口OnShow的时候全部创建这些地雷:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons,Dilei;

type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
dl: array [1..20,1..20] of TDiLei;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
var
i,j :Integer;
begin
for i:= 1 to 20 do
begin
for j := 1 to 20 do
begin
dl[i,j] := TDiLei.create((j-1)*22,(i-1)*22);
end;
end;
end;

end.
但是编译说我的那个"Self.btn := TSpeedButton.Create(Self);"中的self不兼容,怎么做才能显示出来?
...全文
335 34 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
LIANGQIAN1984 2010-01-18
  • 打赏
  • 举报
回复
mark
麦客来了 2010-01-14
  • 打赏
  • 举报
回复
Delphi(Pascal) code

数据是数据,界面操作是界面操作不要混在一起。

TDiLei =class
DL:Boolean;//是不有地雷
State:Integer;//0 没用操作 1 插旗,2 问号 3 爆炸
end;

在定义一个棋盘类
TQiPan=class
RowCount:Integer;//地雷几行几列
ColCount:Integer;
AList:Array of TDiLei;//创建一个数组,保存的地雷

public
procedure SetState(Row,Col:Integer;State:Integer);//设置给定位置的地雷状态
function GetState(Row,Col:Integer):Integer;//得到给定位置的地雷状态
procedure Resetting(IsEnd:Boolean=false) ;//重置 IsEnd=True 设置为开始状态,否则设置为结束状态
end;


//绘制棋盘类
TQiPanDraw=class(TComponent)
Canvas:TCanvas;//要绘制的 画布
Width:Integer;
Heigth:Integer;
public
procedure Draw(QiPan:TQiPan);//绘制,根据给定的棋盘数据
procedure OnClick(Sender:TObject);//在单击事件中根据位置确定点了那个地雷,在根据地雷状态在变换状态,然后在重画画布
end;


改造一下:

//记录地雷位置和状态
TDiLeiState = (dlsNone, dlsFlag, dlsAsk, dlsBlast);
rDiLei = record
ColIndex: Integer;
Row: Integer;
hasDiLei: Boolean;
State: TDileiState;
end;
TDiLei = array of rDiLei;

//棋盘绘制类
TQiPanDraw = class
private
FCanvas: TCanvas: //要绘制的画布
public
procedure Draw(Col, Row: Integer);
end;

//地雷业务处理类(绘制棋盘和地雷状态), 进行点击处理等
TDiLeiBiz = class(TComponent)
private
FDiLei: TDiLei;
FQiPanDraw: TQiPanDraw;
FQiPanClick: TNotifyEvent;
protected
procedure OnClick(Sender: TObject); //保护方法,不需要调用地雷业务处理类的类调用,内部进行点击处理
public
Constructor Create(AOwner: TComponent; Col, Row: Integer); reintroduce; //绘制地盘,初始化地雷结构数据 FDiLei;
end;

//窗体类,完成地雷业务处理类创建,地雷业务处理在TDiLeiBiz类中完全包装了,窗体类不需要知道棋盘和绘制细节
TfrmDiLei = class(TForm)
private
FDiLeiBiz: TDiLeiBiz;
public
end;

implementation

procedure TForm1.FormShow(Sender: TObject);
begin
FDiLeiBiz := TDiLeiBiz.Create(self, 8, 8); //创建一个 8 * 8 的棋盘
end;

end;
jeanler 2010-01-11
  • 打赏
  • 举报
回复
学习了~
salut 2010-01-11
  • 打赏
  • 举报
回复
啊!这么多人!太感谢大家了!
starluck 2010-01-11
  • 打赏
  • 举报
回复
AList:Array of TDiLei

不会玩地雷, 哈哈. 二维图上的东西上面的改为二级数组会不会更方便一些. 虽然存储是一样的.

向各位大哥学习了.
huangheguyun 2010-01-11
  • 打赏
  • 举报
回复
学习经验了。8楼有QQ号吗?
whf1121 2010-01-10
  • 打赏
  • 举报
回复
TSpeedButton.Create(Form1);
hill_qd 2010-01-10
  • 打赏
  • 举报
回复
salut:你好,我看见你的程序了,你仔细看看TSpeedButton.Create(AOwner: TComponent),这个AOwner是这个speedbutton的属主,应该是一个TComponent类型或者更高的,在你的程序中,这些speedbutton是放在form1上面的,也就是说你应该把form1传递给他
sanguomi 2010-01-09
  • 打赏
  • 举报
回复
同意8楼的意见
D版比当年大富翁差的不是一点半点
如今的CSDN D版 水帖比技术帖还多,技术问题都没人讨论
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
再补充一点个人体会:
DELPHI的低门槛,使人容易忽视基本的东西。
很长时间里,我对一些基本概念都搞不清或者说很模糊,并且还很得意:瞧,咱写的程序都可以卖钱了。
想起来真是汗颜。
只是从去年写那个英文软件开始,才努力一个一个地尽量搞清基本概念。三个月下来,感觉收获很大。
楼主搞不清创建一个按钮需要OWNER和PARENT,实际上就是对DELPHI的继承关系缺乏清晰一点的概念,看看书就明白了。
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 harryfin 的回复:]
谁说类一定就要有数据成员的?
[/Quote]

我也没说一定要有。
不过,你愿意设计一个没有数据成员的地雷类吗?
一般只是测试验证等时才写简单的无成员无方法的类吧。
我觉得,不好的设计,抽象度不够的设计,还不如不用OO。PO或者说OP,有人就很喜欢比如LINUS,据说他特别讨厌C++而只用C。
我玩了几年的D了,水平一直很菜。
我是学中文的,写了几个共享软件,基本都是PO。
去年写了个英文共享软件,规模较大,才开始有意识地用OO设计,封继多的确是好东西。这也是被逼的,不然维护吃不消。
也是从去年开始,才看看VCL源码,很多例子可以直接套的。
我是看到并且觉得LZ的设计不好,才直言指出。当然,这是个人观点。
如果大家仅仅只是告诉他SELF编译不过的原因,我觉得没有多少帮助,这与LZ声明的想学OO关系不大。
因为看的不够多,孤陋寡闻难免,所以,我希望我是错的。
一片冰心,明了者自当心领神会。
顺便说一句,我虽然注册了几年,但也就是从去年九十月起真正开始泡这坛子,总的感觉,比当年的大富翁差。
Harryfin 2010-01-09
  • 打赏
  • 举报
回复
谁说类一定就要有数据成员的?
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 zyxip 的回复:]
Delphi(Pascal) code
数据是数据,界面操作是界面操作不要混在一起。

TDiLei=class
DL:Boolean;//是不有地雷
State:Integer;//0 没用操作1 插旗,2 问号3 爆炸end;

在定义一个棋盘类
TQiPan=class
RowCount:Integer;//地雷几行几列
ColCount:Integer;
AList:Arrayof TDiLei;//创建一个数组,保存的地雷

publicprocedure SetState(Row,Col:Integer;State:Integer);//设置给定位置的地雷状态function GetState(Row,Col:Integer):Integer;//得到给定位置的地雷状态procedure Resetting(IsEnd:Boolean=false) ;//重置 IsEnd=True 设置为开始状态,否则设置为结束状态end;//绘制棋盘类
TQiPanDraw=class(TComponent)
Canvas:TCanvas;//要绘制的 画布
Width:Integer;
Heigth:Integer;
publicprocedure Draw(QiPan:TQiPan);//绘制,根据给定的棋盘数据procedure OnClick(Sender:TObject);//在单击事件中根据位置确定点了那个地雷,在根据地雷状态在变换状态,然后在重画画布end;

基本的思路就是这样。只要能有条理的分析问题,平时做事也有条理,就容易理解。
各个对象各干各的,只做有必要交互而且还是简单明了。

[/Quote]

高手,学习了。思路或者说思想是万花油,治疗烫伤特有效。:)
我也是最近开始学用OOP的。真是好东西,现在有点感觉了。
我有个程序,有5种不同的子窗体,要命的是,有时还需要它是普通窗体。虽然可以变通处理,但很麻烦,而且父子之间通信也麻烦,调用某个子窗体的属性或方法往往要遍历。现在引入一个basechild,里面抽象定义了一些可以覆盖的虚方法,然后所有的子窗体都继承它,就非常简单了。这就是所谓的多态吧。
lhy 2010-01-09
  • 打赏
  • 举报
回复
另外楼主的代码unit Dilei还要在implementation里面USES一下UNIT1
ZyxIp 2010-01-09
  • 打赏
  • 举报
回复

数据是数据,界面操作是界面操作不要混在一起。

TDiLei =class
DL:Boolean;//是不有地雷
State:Integer;//0 没用操作 1 插旗,2 问号 3 爆炸
end;

在定义一个棋盘类
TQiPan=class
RowCount:Integer;//地雷几行几列
ColCount:Integer;
AList:Array of TDiLei;//创建一个数组,保存的地雷

public
procedure SetState(Row,Col:Integer;State:Integer);//设置给定位置的地雷状态
function GetState(Row,Col:Integer):Integer;//得到给定位置的地雷状态
procedure Resetting(IsEnd:Boolean=false) ;//重置 IsEnd=True 设置为开始状态,否则设置为结束状态
end;


//绘制棋盘类
TQiPanDraw=class(TComponent)
Canvas:TCanvas;//要绘制的 画布
Width:Integer;
Heigth:Integer;
public
procedure Draw(QiPan:TQiPan);//绘制,根据给定的棋盘数据
procedure OnClick(Sender:TObject);//在单击事件中根据位置确定点了那个地雷,在根据地雷状态在变换状态,然后在重画画布
end;



基本的思路就是这样。只要能有条理的分析问题,平时做事也有条理,就容易理解。
各个对象各干各的,只做有必要交互而且还是简单明了。
dd_zhouqian 2010-01-09
  • 打赏
  • 举报
回复
mark
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 kfcoffe 的回复:]
引用 19 楼 iseekcode 的回复:
引用 14 楼 kfcoffe 的回复:
mark 学习 以后有问题就找你了 iseekcode  哈哈


不敢当,我是一只老老老菜鸟,想要飞却怎么也飞不高。:)


慢慢飞,高手一般都这么谦虚的。可以理解。
[/Quote]

呵呵,我能理解,只是希望自己理解错了。
kfcoffe 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 iseekcode 的回复:]
引用 14 楼 kfcoffe 的回复:
mark 学习 以后有问题就找你了 iseekcode  哈哈


不敢当,我是一只老老老菜鸟,想要飞却怎么也飞不高。:)
[/Quote]

慢慢飞,高手一般都这么谦虚的。可以理解。
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 kfcoffe 的回复:]
mark 学习 以后有问题就找你了 iseekcode  哈哈
[/Quote]

不敢当,我是一只老老老菜鸟,想要飞却怎么也飞不高。:)
iseekcode 2010-01-09
  • 打赏
  • 举报
回复
明白就好,理解万岁:)

实话实说,我也是OOP初学者。
我以为,基础很重要,因为我吃过苦头。
如果,请Harryfin原谅,如果你认为LZ(也请LZ原谅)在还没有搞清楚创建一个空件需要一个PARENT的情况下,就认为他已经搞清楚了wrapper概念并且LZ认为自己的类没什么问题,那么,我错了,我道歉。

所以,你的意思我也明白。
加载更多回复(13)

5,928

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧