Classes - Inheritance - how to add an additional parameter to the constructor? lazarus / 21-General ---------------------------------------------------------------------- rwebb616 · 2021-05-06 23:17 Here is what I have currently: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit headsup.classes.word; {$mode objfpc}{$H+} interface uses  Classes, SysUtils; type   { TWord }   TWord = class   private    FCategory : string;    FWord : string;    FPlayed : boolean;   public    constructor Create (Category : String; Word : string; Played : boolean);    property Word: String Read FWord Write FWord;    property Category : String Read FCategory Write FCategory;    property Played : Boolean Read FPlayed Write FPlayed;   end;   { TPlayedWord }   TPlayedWord = class(Tword)     constructor Create (Category : String; Word : String; Played : boolean; Correct : boolean); override;     private      FCorrect:boolean;    public      property Correct : Boolean Read FCorrect Write FCorrect;    end; implementation { TPlayedWord } constructor TPlayedWord.Create(Correct: boolean);begin  inherited;  FPlayed := Played;  FCategory := Category;  FWord := Word;  FCorrect := Correct;end; { TWord } constructor TWord.Create(Category: String; Word: string; Played : boolean);begin  FPlayed := Played;  FCategory := Category;  FWord := Word; end; end.  What am I doing wrong?  TPlayedword is inheriting from Tword and I want to be able to pass one additional parameter to TPlayedword - the "Correct" boolean. Compiler is complaining about Duplicate identifier but when I remove the three original ones it gives me a different error "There is no method in ancestor class to be overridden constructor create(boolean); Rich ---------------------------------------------------------------------- cdbc · 2021-05-06 23:35 Hi Overload the constructor Regards Benny ---------------------------------------------------------------------- zamronypj · 2021-05-07 00:14 Quote from: rwebb616 on May 07, 2021, 01:17:33 amHere is what I have currently: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit headsup.classes.word; {$mode objfpc}{$H+} interface uses  Classes, SysUtils; type   { TWord }   TWord = class   private    FCategory : string;    FWord : string;    FPlayed : boolean;   public    constructor Create (Category : String; Word : string; Played : boolean);    property Word: String Read FWord Write FWord;    property Category : String Read FCategory Write FCategory;    property Played : Boolean Read FPlayed Write FPlayed;   end;   { TPlayedWord }   TPlayedWord = class(Tword)     constructor Create (Category : String; Word : String; Played : boolean; Correct : boolean); override;     private      FCorrect:boolean;    public      property Correct : Boolean Read FCorrect Write FCorrect;    end; implementation { TPlayedWord } constructor TPlayedWord.Create(Correct: boolean);begin  inherited;  FPlayed := Played;  FCategory := Category;  FWord := Word;  FCorrect := Correct;end; { TWord } constructor TWord.Create(Category: String; Word: string; Played : boolean);begin  FPlayed := Played;  FCategory := Category;  FWord := Word; end; end.  What am I doing wrong?  TPlayedword is inheriting from Tword and I want to be able to pass one additional parameter to TPlayedword - the "Correct" boolean. Compiler is complaining about Duplicate identifier but when I remove the three original ones it gives me a different error "There is no method in ancestor class to be overridden constructor create(boolean); Rich duplicate error because you use parameter name  Category, Word, Played while you have property with same name. Rename parameter to different names such as aCategory etc. Override is not needed as parent method is not same in signature and not marked as virtual Code: [Select]constructor Create (aCategory : String; aWord : String; aPlayed : boolean; aCorrect : boolean); Code: [Select]constructor TPlayedWord.Create (aCategory : String; aWord : String; aPlayed : boolean; aCorrect : boolean); begin       inherited create(aCategory, aWord, aPlayed);       fCorrect := aCorrect; end; Also using word as property name is not recommended as pascal has type with name word. ---------------------------------------------------------------------- zamronypj · 2021-05-07 00:36 Quote from: jamie on May 07, 2021, 02:07:08 am"WORD" is a reserved word. It is a Type that is 2 bytes wide.. Use something else in its place. Like AGameWord or something.  At least don't try do make a variable := WORD; incorrect. word is not reserved word but type definition https://www.freepascal.org/docs-html/ref/refse3.html ---------------------------------------------------------------------- egsuh · 2021-05-07 02:22 You should add virtual to TWord.Create to override it. ---------------------------------------------------------------------- rwebb616 · 2021-05-07 02:53 I have this now and it seems to work: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit headsup.classes.word; {$mode objfpc}{$H+} interface uses  Classes, SysUtils; type   { TWord }   TWord = class   private    FCategory : string;    FWord : string;    FPlayed : boolean;   public    constructor Create (aCategory : String; aWord : string; aPlayed : boolean);    property Word: String Read FWord Write FWord;    property Category : String Read FCategory Write FCategory;    property Played : Boolean Read FPlayed Write FPlayed;   end;   { TPlayedWord }   TPlayedWord = class(Tword)     constructor Create (aCategory: String; aWord: string; aPlayed : boolean; aCorrect: boolean);     private    FCorrect:boolean;    public      property Correct : Boolean Read FCorrect Write FCorrect;    end; implementation { TPlayedWord } constructor TPlayedWord.Create(aCategory: String; aWord: string; aPlayed : boolean; aCorrect: boolean);begin  FPlayed := aPlayed;  FCategory := aCategory;  FWord := aWord;  FCorrect := aCorrect;end; { TWord } constructor TWord.Create(aCategory: String; aWord: string; aPlayed : boolean);begin  FPlayed := aPlayed;  FCategory := aCategory;  FWord := aWord; end; end.  I don't know if it's good practice or not.  By the way I've been wondering what the 'a' signifies in the declaration of the procedures?  I know 'F' usually means Field. ---------------------------------------------------------------------- rwebb616 · 2021-05-07 02:56 Quote from: zamronypj on May 07, 2021, 02:14:42 amduplicate error because you use parameter name  Category, Word, Played while you have property with same name. Rename parameter to different names such as aCategory etc. Override is not needed as parent method is not same in signature and not marked as virtual Code: [Select]constructor Create (aCategory : String; aWord : String; aPlayed : boolean; aCorrect : boolean); Code: [Select]constructor TPlayedWord.Create (aCategory : String; aWord : String; aPlayed : boolean; aCorrect : boolean); begin       inherited create(aCategory, aWord, aPlayed);       fCorrect := aCorrect; end; Also using word as property name is not recommended as pascal has type with name word. This is what seemed to resolve it - I named them as you did and it compiled.  I will change Word at some point.. just didn't feel like searching through my whole codebase to find where I'm using it and change it. (I know the IDE can probably do this quickly) Rich ---------------------------------------------------------------------- egsuh · 2021-05-07 03:23 Quote I've been wondering what the 'a' signifies in the declaration of the procedures?It doesn't mean anything special. Just to escape using the same identifier --- you have declared Category, Word, etc. as property name within the class. Parameter names have significance only within the procedure/function, so it's relatively unimportant how to name them. ---------------------------------------------------------------------- howardpc · 2021-05-07 03:52 Quote from: rwebb616 on May 07, 2021, 04:53:53 am  By the way I've been wondering what the 'a' signifies in the declaration of the procedures? A consistently applied naming convention can improve readability of code, and go some way to save you from making simple errors. An obvious "convention" you can apply is to avoid using the same identifier to refer to different variables (with the exception of trivial examples such as say i for an integer loop variable). The objfpc mode enforces this in some situations. While some coders find this unnecessarily restrictive, personally I like tramlines that keep you away from potential ambiguity and confusion. Prefixing parameter names with "a" (if done consistently) gives an immediate visual cue that this is not a locally declared or global variable, but a parameter. In short programs this makes little difference. However, when you write code with thousands of lines, conventions such as this can really help in deciphering code that uses literally hundreds of variables and parameters. Thinking "count" is a global variable or public property when in the current scope it is actually a parameter of your current hundred-line function (whose header has scrolled out of view) leads to immediate grief. Making a visual distinction between them at the declaration stage avoids that potential confusion. ---------------------------------------------------------------------- rwebb616 · 2021-05-07 03:56 I understand the reasoning - just didn't know if there was a particular meaning for 'A'..  as people prefix class fields with 'F' for Field.  Didn't know if there was a similar nomenclature for 'A' or 'a' other than it's just conveniently the first letter of the alphabet! ---------------------------------------------------------------------- lucamar · 2021-05-07 04:01 Quote from: rwebb616 on May 07, 2021, 04:53:53 amBy the way I've been wondering what the 'a' signifies in the declaration of the procedures?  I know 'F' usually means Field. Besides what Howard wrote, the origin of the "A" prefix convention was to mean the generic English "a" ("one") as in "a category", "a string", "a whatever", etc. That's why sometimes you'll see e.g. "AnObject" or "AnInteger". Though, through internacionalization, it has almost lost that original "meaning". But no, it's not because "it is the first letter of the alphabet" ---------------------------------------------------------------------- rwebb616 · 2021-05-07 04:03 Quote from: lucamar on May 07, 2021, 06:01:07 am Besides what Howard wrote, the origin of the "A" prefix convention was to mean the generic English "a" ("one") as in "a category", "a string", "a whatever", etc. That's why sometimes you'll see e.g. "AnObject: TObject". Though, through internacionalization, it has almost lost that original "meaning". Ahh.. I wondered if that was it because, yes I had seen both AnObject and AObject before in example code. ---------------------------------------------------------------------- PascalDragon · 2021-05-07 13:55 Quote from: rwebb616 on May 07, 2021, 05:56:07 amI understand the reasoning - just didn't know if there was a particular meaning for 'A'..  as people prefix class fields with 'F' for Field.  Didn't know if there was a similar nomenclature for 'A' or 'a' other than it's just conveniently the first letter of the alphabet! The 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers). ---------------------------------------------------------------------- Bart · 2021-05-07 15:49 Quote from: PascalDragon on May 07, 2021, 03:55:28 pmThe 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers). I always imagined that the A just was that: a, as in AString meaning "a string", which more or less equals "some string". Another dream just shattered ... Bart ---------------------------------------------------------------------- lucamar · 2021-05-07 20:42 Quote from: Bart on May 07, 2021, 05:49:17 pmQuote from: PascalDragon on May 07, 2021, 03:55:28 pmThe 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers).I always imagined that the A just was that: a, as in AString meaning "a string", which more or less equals "some string".. Yeah, I though so too (more so when you find code that instead uses "the", as in "TheString") but after the Dragon's answer I am starting to think that it really means (or meant) nothing and that any interpretation is purely subjective ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-05-07 21:50 Hey All, Quote from: PascalDragon on May 07, 2021, 03:55:28 pmThe 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers). I actually assumed it in this way, maybe because of the way all the other prefixes have been selected: T is for TypeF is for FieldP is for Pointer So for me it made sense that A would be for Argument. I did, nonetheless, miss the fact that P, for Parameter was already used Cheers, Gus PS: And if I'm not mistaken, with this post I've earned my chops as Hero Member, YAY, LOL!!! ---------------------------------------------------------------------- VTwin · 2021-05-07 21:53 Quote from: PascalDragon on May 07, 2021, 03:55:28 pmThe 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers). Interesting, I assumed as lucamar and Bart did. This makes me appreciate the convention much more.