Lazarus

Programming => General => Topic started by: rwebb616 on May 07, 2021, 01:17:33 am

Title: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: rwebb616 on May 07, 2021, 01:17:33 am
Here is what I have currently:

Code: Pascal  [Select][+][-]
  1. unit headsup.classes.word;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.  
  12.   { TWord }
  13.  
  14.   TWord = class
  15.  
  16.   private
  17.     FCategory : string;
  18.     FWord : string;
  19.     FPlayed : boolean;
  20.  
  21.   public
  22.     constructor Create (Category : String; Word : string; Played : boolean);
  23.     property Word: String Read FWord Write FWord;
  24.     property Category : String Read FCategory Write FCategory;
  25.     property Played : Boolean Read FPlayed Write FPlayed;
  26.  
  27.   end;
  28.  
  29.   { TPlayedWord }
  30.  
  31.   TPlayedWord = class(Tword)
  32.  
  33.     constructor Create (Category : String; Word : String; Played : boolean; Correct : boolean); override;
  34.  
  35.     private
  36.       FCorrect:boolean;
  37.     public
  38.       property Correct : Boolean Read FCorrect Write FCorrect;
  39.  
  40.  
  41.   end;
  42.  
  43. implementation
  44.  
  45. { TPlayedWord }
  46.  
  47. constructor TPlayedWord.Create(Correct: boolean);
  48. begin
  49.   inherited;
  50.   FPlayed := Played;
  51.   FCategory := Category;
  52.   FWord := Word;
  53.   FCorrect := Correct;
  54. end;
  55.  
  56. { TWord }
  57.  
  58. constructor TWord.Create(Category: String; Word: string; Played : boolean);
  59. begin
  60.   FPlayed := Played;
  61.   FCategory := Category;
  62.   FWord := Word;
  63.  
  64. end;
  65.  
  66. end.
  67.  

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
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: cdbc on May 07, 2021, 01:35:02 am
Hi
Overload the constructor
Regards Benny
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: zamronypj on May 07, 2021, 02:14:42 am
Here is what I have currently:

Code: Pascal  [Select][+][-]
  1. unit headsup.classes.word;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.  
  12.   { TWord }
  13.  
  14.   TWord = class
  15.  
  16.   private
  17.     FCategory : string;
  18.     FWord : string;
  19.     FPlayed : boolean;
  20.  
  21.   public
  22.     constructor Create (Category : String; Word : string; Played : boolean);
  23.     property Word: String Read FWord Write FWord;
  24.     property Category : String Read FCategory Write FCategory;
  25.     property Played : Boolean Read FPlayed Write FPlayed;
  26.  
  27.   end;
  28.  
  29.   { TPlayedWord }
  30.  
  31.   TPlayedWord = class(Tword)
  32.  
  33.     constructor Create (Category : String; Word : String; Played : boolean; Correct : boolean); override;
  34.  
  35.     private
  36.       FCorrect:boolean;
  37.     public
  38.       property Correct : Boolean Read FCorrect Write FCorrect;
  39.  
  40.  
  41.   end;
  42.  
  43. implementation
  44.  
  45. { TPlayedWord }
  46.  
  47. constructor TPlayedWord.Create(Correct: boolean);
  48. begin
  49.   inherited;
  50.   FPlayed := Played;
  51.   FCategory := Category;
  52.   FWord := Word;
  53.   FCorrect := Correct;
  54. end;
  55.  
  56. { TWord }
  57.  
  58. constructor TWord.Create(Category: String; Word: string; Played : boolean);
  59. begin
  60.   FPlayed := Played;
  61.   FCategory := Category;
  62.   FWord := Word;
  63.  
  64. end;
  65.  
  66. end.
  67.  

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.
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: zamronypj on May 07, 2021, 02:36:16 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
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: egsuh on May 07, 2021, 04:22:04 am
You should add virtual to TWord.Create to override it.
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: rwebb616 on May 07, 2021, 04:53:53 am
I have this now and it seems to work:

Code: Pascal  [Select][+][-]
  1. unit headsup.classes.word;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.  
  12.   { TWord }
  13.  
  14.   TWord = class
  15.  
  16.   private
  17.     FCategory : string;
  18.     FWord : string;
  19.     FPlayed : boolean;
  20.  
  21.   public
  22.     constructor Create (aCategory : String; aWord : string; aPlayed : boolean);
  23.     property Word: String Read FWord Write FWord;
  24.     property Category : String Read FCategory Write FCategory;
  25.     property Played : Boolean Read FPlayed Write FPlayed;
  26.  
  27.   end;
  28.  
  29.   { TPlayedWord }
  30.  
  31.   TPlayedWord = class(Tword)
  32.  
  33.     constructor Create (aCategory: String; aWord: string; aPlayed : boolean; aCorrect: boolean);
  34.  
  35.     private
  36.       FCorrect:boolean;
  37.     public
  38.       property Correct : Boolean Read FCorrect Write FCorrect;
  39.  
  40.  
  41.   end;
  42.  
  43. implementation
  44.  
  45. { TPlayedWord }
  46.  
  47. constructor TPlayedWord.Create(aCategory: String; aWord: string; aPlayed : boolean; aCorrect: boolean);
  48. begin
  49.   FPlayed := aPlayed;
  50.   FCategory := aCategory;
  51.   FWord := aWord;
  52.   FCorrect := aCorrect;
  53. end;
  54.  
  55. { TWord }
  56.  
  57. constructor TWord.Create(aCategory: String; aWord: string; aPlayed : boolean);
  58. begin
  59.   FPlayed := aPlayed;
  60.   FCategory := aCategory;
  61.   FWord := aWord;
  62.  
  63. end;
  64.  
  65. end.
  66.  

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. 
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: rwebb616 on May 07, 2021, 04:56:03 am
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.

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
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: egsuh on May 07, 2021, 05:23:52 am
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.
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: howardpc on May 07, 2021, 05:52:57 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.
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: rwebb616 on May 07, 2021, 05:56:07 am
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! :)

Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: lucamar on May 07, 2021, 06:01:07 am
By 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" ;D
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: rwebb616 on May 07, 2021, 06:03:00 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.

Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: PascalDragon on May 07, 2021, 03:55:28 pm
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! :)

The 'A' or 'a' prefix stands for 'argument' (aka 'parameter' due to 'P' already being used for pointers).
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: Bart on May 07, 2021, 05:49:17 pm
The '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
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: lucamar on May 07, 2021, 10:42:59 pm
The '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 ;)
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: Gustavo 'Gus' Carreno on May 07, 2021, 11:50:09 pm
Hey All,

The '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:

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!!!
Title: Re: Classes - Inheritance - how to add an additional parameter to the constructor?
Post by: VTwin on May 07, 2021, 11:53:21 pm
The '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.
TinyPortal © 2005-2018