在 class 声明中定义方法体?
Defining method body inside class declaration?
我试图在 Free Pascal 的 class 声明中定义 class 方法,但我无法在网上找到任何示例。目前我必须这样做:
unit Characters;
{$mode objfpc}{$H+}
// Public
interface
type
TCharacter = class(TOBject)
private
FHealth, FAttack, FDefence: Integer;
procedure SetHealth(newValue: Integer);
public
constructor Create(); virtual;
procedure SayShrek();
function GetHealth(): Integer;
published
property Health: Integer read GetHealth write SetHealth;
end;
// Private
implementation
constructor TCharacter.Create;
begin
WriteLn('Ogres have LAYERS!');
end;
procedure TCharacter.SayShrek;
begin
WriteLn('Shrek!');
end;
procedure TCharacter.SetHealth(newValue: Integer);
begin
FHealth:= FHealth + newValue;
end;
function TCharacter.GetHealth() : Integer;
begin
GetHealth:= FHealth;
end;
end.
有什么方法可以让它更干净一点吗?在别处定义所有内容看起来杂乱无章。
编辑:
为了澄清,我想按照以下方式做一些事情:
TMyClass = class(TObject)
public
procedure SayHi();
begin
WriteLn('Hello!');
end;
end;
而不是必须进一步定义它。这可能吗?
不,你不能这样做。 Pascal 有一个单通道编译器从一开始就是为单通道编译而设计的,所以你不能在它被声明之前使用它。
伪代码中的一个简单示例:
MyClass = class
procedure MethodA;
begin
MethodB; <== At this point the compiler knows nothing about MethodB
end;
procedure MethodB;
begin
end;
end;
这就是为什么每个单元至少有两个部分:interface
(声明,您可以将其视为C++头文件)和implementation
。
然而,在实现循环声明的语言语法中有一些技巧,您可以在其中使用前向声明。
指点:
PMyRec = ^TMyRec; // Here is TMyRec is not declared yet but compiler can to handle this
TMyRec = record
NextItem: PMyRec;
end;
对于类:
MyClassA = class; // Forward declaration, class will be fully declared later
MyClassB = class
SomeField: MyClassA;
end;
MyClassA = class
AnotherField: MyClassB;
end;
在 IDE 中,您可以使用 Shift+Ctrl+Up/Down
键在项目的声明和实现之间导航。
这在 Pascal 中是不可能的。它的语法不允许它。
Pascal 的基本设计是将单元分为interface
(可以做什么?)和implementation
(事情是如何完成的?)。
编译器在解析 implementation
部分之前读取所有 interface
部分。你可能从 C 语言中知道这一点。 implementation
可以描述为 *.c 文件,而 interface
相当于 C 中的 *.h 文件。
此外,此类代码会严重降低 interface
部分(f.i。class 声明)的可读性。
您希望从中得到什么好处?
我试图在 Free Pascal 的 class 声明中定义 class 方法,但我无法在网上找到任何示例。目前我必须这样做:
unit Characters;
{$mode objfpc}{$H+}
// Public
interface
type
TCharacter = class(TOBject)
private
FHealth, FAttack, FDefence: Integer;
procedure SetHealth(newValue: Integer);
public
constructor Create(); virtual;
procedure SayShrek();
function GetHealth(): Integer;
published
property Health: Integer read GetHealth write SetHealth;
end;
// Private
implementation
constructor TCharacter.Create;
begin
WriteLn('Ogres have LAYERS!');
end;
procedure TCharacter.SayShrek;
begin
WriteLn('Shrek!');
end;
procedure TCharacter.SetHealth(newValue: Integer);
begin
FHealth:= FHealth + newValue;
end;
function TCharacter.GetHealth() : Integer;
begin
GetHealth:= FHealth;
end;
end.
有什么方法可以让它更干净一点吗?在别处定义所有内容看起来杂乱无章。
编辑:
为了澄清,我想按照以下方式做一些事情:
TMyClass = class(TObject)
public
procedure SayHi();
begin
WriteLn('Hello!');
end;
end;
而不是必须进一步定义它。这可能吗?
不,你不能这样做。 Pascal 有一个单通道编译器从一开始就是为单通道编译而设计的,所以你不能在它被声明之前使用它。
伪代码中的一个简单示例:
MyClass = class
procedure MethodA;
begin
MethodB; <== At this point the compiler knows nothing about MethodB
end;
procedure MethodB;
begin
end;
end;
这就是为什么每个单元至少有两个部分:interface
(声明,您可以将其视为C++头文件)和implementation
。
然而,在实现循环声明的语言语法中有一些技巧,您可以在其中使用前向声明。
指点:
PMyRec = ^TMyRec; // Here is TMyRec is not declared yet but compiler can to handle this
TMyRec = record
NextItem: PMyRec;
end;
对于类:
MyClassA = class; // Forward declaration, class will be fully declared later
MyClassB = class
SomeField: MyClassA;
end;
MyClassA = class
AnotherField: MyClassB;
end;
在 IDE 中,您可以使用 Shift+Ctrl+Up/Down
键在项目的声明和实现之间导航。
这在 Pascal 中是不可能的。它的语法不允许它。
Pascal 的基本设计是将单元分为interface
(可以做什么?)和implementation
(事情是如何完成的?)。
编译器在解析 implementation
部分之前读取所有 interface
部分。你可能从 C 语言中知道这一点。 implementation
可以描述为 *.c 文件,而 interface
相当于 C 中的 *.h 文件。
此外,此类代码会严重降低 interface
部分(f.i。class 声明)的可读性。
您希望从中得到什么好处?