Delphi self keyword

我只是一个虾纸丫 提交于 2019-12-18 15:35:37

问题


I am learning Delphi reading Marco Cantu's book and it's super complete. It's very clear but I have a doubt about the keyword self. I already have experience with OOP and I have the basics of it. My question is very simple. Can I compare the keyword self (Delphi) to the keyword this (Java)?

When I read on the book about the self used inside record, I got in my mind something like self : Delphi = this : Java. Look at the code I created to make a test:

type
 TMarioKart = packed record
   Character: String;
   Kart: String;
   Tires: String;
   Speed: double;
   Competitive: boolean;
  private
   air-speed: integer;
   ground-speed: integer;
   water-speed: integer;
  public
   constructor Create(Character: string);
   function ShowStats(a: TMarioKart):string; overload;
   function ShowStats(a: TMarioKart; b: TMarioKart): string; overload;
 end;

I am going to cut off the biggest part of the code, I am just showing the constructor here:

constructor TMarioKart.Create(Character: string);
begin
  self.Character := Character;
end;

Using the keyword self here I am referring to the Character of the record, and not to the Character passed in the method. Is this the correct way to use the self? Could it be the brother of Java's this?


回答1:


Yes, Delphi's Self is the direct analogue of Java's this.




回答2:


Self is very similar to this in Java, C++, or C#. However it is a little bit more invoked, as the following code will show.

In Delphi, you can have class methods that are not static but also have a Self pointer, which then obviously does not point to an instance of the class but to the class type itself that the method is called on.

See the output of this program:

program WhatIsSelf;

{$APPTYPE CONSOLE}

type
  TAnimal = class
    procedure InstanceMethod;
    class procedure ClassMethod;
    class procedure StaticClassMethod; static;
  end;

  TDog = class(TAnimal)
  end;

class procedure TAnimal.ClassMethod;
begin
  Writeln(Self.ClassName);
end;

procedure TAnimal.InstanceMethod;
begin
  Writeln(Self.ClassName);
end;

class procedure TAnimal.StaticClassMethod;
begin
//  Writeln(Self.ClassName); // would not compile with error: E2003 Undeclared identifier: 'Self'
end;

var
  t: TAnimal;
begin
  t := TDog.Create;
  t.InstanceMethod;
  t.ClassMethod;

  TAnimal.ClassMethod;
  TDog.ClassMethod;

  Readln;
end.



回答3:


Formally speaking, Self is a normal identifier (that is automatically predeclared in some circumstances).

Self is automatically defined in the implementation of methods and class methods and its purpose there is similar to this in Java as already mentioned. The underlying technology is analogous to the Result variable in ordinary functions.

In other words, there is no self keyword (that's why it's typically written with an uppercase S). Whenever you want (and can [*]), you may introduce your own Self variable, method or class.

type
  // TForm1 ommitted

  Self = class
    function Self: Integer;
  end;

function Self.Self: Integer;
begin
  Result := SizeOf(Self);
end;

You'll have of course difficulties to instantiate an object of this type within a method, in these cases, you have to use it through an adapter function (or procedure):

function UseSelf: Integer;
var
  S: Self;
begin
  S := Self.Create;
  Result := S.Self;
  S.Free;
end;

function VarSelf: Integer;
var
  Self: Integer;
begin
  Self := SizeOf(Result);
  Result := Self;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(IntToStr(UseSelf)+' '+IntToStr(VarSelf));
end;


[*] You cannot declare a Self variable within methods, because there is already such a declaration and that's exactly what the error says:

Identifier redeclared: 'Self'



来源:https://stackoverflow.com/questions/38893970/delphi-self-keyword

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!