Recent

Author Topic: Why can't create be overridden  (Read 5548 times)

Birger52

  • Sr. Member
  • ****
  • Posts: 309
Why can't create be overridden
« on: May 11, 2019, 02:33:04 pm »
I'm thinking there must be someting I have my head around the wrong way.
Creating a class of my own.

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyThumbData = class(TObject)
  3.   private
  4.  ...
  5.   public
  6.      constructor Create; override;
  7. ...
  8.  

I get a compiler error:
Quote
mythumbdata.pas(17,18) Error: There is no method in an ancestor class to be overridden: "constructor Create;"

So I look up TObject (https://www.freepascal.org/docs-html/rtl/system/tobject.html)
Code: Pascal  [Select][+][-]
  1. type TObject = class
  2. public
  3.   constructor Create;
  4. ...

So is the documentation or the compiler right?
I have to remove the override - compiler insists it is en error, and the program will not run with it, so I guess compiler wins the contest.

In the create method of my new class
Code: Pascal  [Select][+][-]
  1. constructor TMyThumbData.Create;
  2. begin
  3.   inherited Create;
  4. ...
  5.  
There is no error or warning - so the Create that can not be overriden do exist...

I know, it is only TObject, so it doesn't really matter (TObject.Create does nothing).
An maybe I am wearing both belt and suspenders - but I don't see doing anything "errorneous".

In fact, the only "error" I can find in this, is that the compiler, will not let me override TObject.Create
Or is there some reason that it for TObject is not allowed, or other situations it is not allowed?
Lazarus 2.0.8 FPC 3.0.4
Win7 64bit
Playing and learning - strictly for my own pleasure.

korba812

  • Sr. Member
  • ****
  • Posts: 392
Re: Why can't create be overridden
« Reply #1 on: May 11, 2019, 03:10:55 pm »
from https://www.freepascal.org/docs-html/rtl/system/tobject.create.html:

Create creates a new instance of TObject. Currently it does nothing. It is also not virtual, so there is in principle no need to call it directly.

Birger52

  • Sr. Member
  • ****
  • Posts: 309
Re: Why can't create be overridden
« Reply #2 on: May 11, 2019, 03:17:59 pm »
That does not explain, why it is illegal to override it...
Lazarus 2.0.8 FPC 3.0.4
Win7 64bit
Playing and learning - strictly for my own pleasure.

korba812

  • Sr. Member
  • ****
  • Posts: 392
Re: Why can't create be overridden
« Reply #3 on: May 11, 2019, 03:25:20 pm »
Yes, it is. TObject.Create is not virtual. Only virtual methods can be overridden.

https://www.freepascal.org/docs-html/ref/refsu27.html

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Why can't create be overridden
« Reply #4 on: May 11, 2019, 04:12:20 pm »
Calling "inherited" and using "override" are independent things.

Calling "inherited" basically means: From the base class.
You can call any method of the base-class (or the base-class' base(s)) using inherited.
Code: Pascal  [Select][+][-]
  1. Procedure TMyClass.Foo;
  2. begin
  3.   inherited Bar; // fine as long as there is a Bar in the inheritance
  4. end;
  5.  

Usually you use "inherited", if your class "hides" a method in the base class.
You can hide it by
- Just declaring it (no override). That will give a warning, and might not behave as you expect. But you can do it.
- "override" it. If the parent is "virtual"
- "reintroduce" it (google it, if interested)

Normally a constructor you just declare it. (There are virtual constructors, but that is only if you use "class of TMyClass" - different topic - do not worry about it for now)

So using "inherited" does not require virtual and override.

Birger52

  • Sr. Member
  • ****
  • Posts: 309
Re: Why can't create be overridden
« Reply #5 on: May 11, 2019, 05:45:24 pm »
OK Thx.

Didn't know only virtual methods could be overwritten.
Lazarus 2.0.8 FPC 3.0.4
Win7 64bit
Playing and learning - strictly for my own pleasure.

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Why can't create be overridden
« Reply #6 on: May 14, 2019, 01:31:05 pm »
Quote
"reintroduce" it (google it, if interested)

nb: in addition to information, with a "reintroduce; overload;" method, you have to think about setting the property "OldCreateOrder:= true;", if we want to create a custom constructor of a TForm or a TDatamodule, for example.
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Why can't create be overridden
« Reply #7 on: May 14, 2019, 04:03:31 pm »
Quote
"reintroduce" it (google it, if interested)

nb: in addition to information, with a "reintroduce; overload;" method, you have to think about setting the property "OldCreateOrder:= true;", if we want to create a custom constructor of a TForm or a TDatamodule, for example.
I suggest to delete that because it is nonsense...
Specialize a type, not a var.

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Why can't create be overridden
« Reply #8 on: May 14, 2019, 06:26:00 pm »
Indeed.
I haven't been precise enough: my remark is in the context, where we hide one or more components by moving them into the private section of a container like TForm, TDatamodule, TFrame, ..., then we search them in a custom "reintroduce; overload;" constructor with findComponent(['foo1']) as TFoo; and registerClasses([TFoo, ...]); in the initialization unit's part.
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Why can't create be overridden
« Reply #9 on: May 15, 2019, 01:55:31 am »
Usually you use "inherited", if your class "hides" a method in the base class.
You can hide it by
- Just declaring it (no override). That will give a warning, and might not behave as you expect. But you can do it.

Normally a constructor you just declare it.

I don't follow. It is normal to declare it without override, but it might not behave as you expect? That sounds contradictory. Could you clarify?
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Why can't create be overridden
« Reply #10 on: May 15, 2019, 02:32:46 am »
Usually you use "inherited", if your class "hides" a method in the base class.
You can hide it by
- Just declaring it (no override). That will give a warning, and might not behave as you expect. But you can do it.


Normally a constructor you just declare it.

I don't follow. It is normal to declare it without override, but it might not behave as you expect? That sounds contradictory. Could you clarify?

The green part was about normal methods. Only the last (black) line referred to constructors.
I explained this part on normal methods, because virtual constructors is an advanced topic, which I did not want to introduce then.

While the topic is about constructors, it also is about the use of "inherited".
Probably "inherited" in this case was observed by the OT as part of the code created for the constructor (by codetools).
But in tutorials "inherited" is often introduced together with virtual/override. Which would explain why the OT wondered about the constructor not using virtual/override, when at the other hand it does use "inherited".

I pointed out that in a normal method you can use "inherited" without virtual/override too.
But "reintroducing" a normal method instead of overriding it, may not be what the OT may expect. (That of course is me guessing, I have no real knowledge about the expectations of the OT)

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Why can't create be overridden
« Reply #11 on: May 15, 2019, 03:25:40 am »
Martin_fr,

Got it. I did not follow the distinction you made between normal methods and constructors. I see that now. I have not played with "reintroducing', and am not inclined to. I have not always been clear on the best practices for declaring constructors (virtual or not). Thanks for the clarification.

Cheers,
VTwin
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Why can't create be overridden
« Reply #12 on: May 15, 2019, 09:54:10 am »
@Thaddy and @VTwin: everything Martin_fr says are the basics, and cover 95% of programming cases.
For those who are curious and wondering what "reintroduce" is for, you can read this (Marco Cantu's article entitled "20 rules for OOP In Delphi", and for Lazarus too, so).
This article can be easily found on the web, for example here:
http://zeus.nyf.hu/~bajalinov/my_special/SW/Delphi%20eBooks/Delphi/Delphi%20-%2020%20Rules%20for%20OOP%20in%20Delphi.pdf .
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11384
  • FPC developer.
Re: Why can't create be overridden
« Reply #13 on: May 15, 2019, 10:21:07 am »
Just for fun: if you start using virtual constructors you'll often use "class of" types.

Checking if a "class of x" typed variable inherits from class y has a famous gotcha, you need to use x.inheritsfrom(y), not IS which won't compile or not work properly.

Code: [Select]
{$mode delphi}
type   tx = class
           end;
       txclass = class of tx;
       ty = class(tx)
            y:integer;
          end;
       tyy = class(ty)
            y2:integer;
          end;

       tz = class(tx)
            y:integer;
          end;
         
 
var x : txclass;

begin
  x:=ty;
 { if x is ty then               // won't compile
    writeln('x is ty');         
  if x is tz then
    writeln('x is tz');}
   if x.inheritsfrom(ty) then
    writeln('x inheritsfrom ty');         
   if x.inheritsfrom(tz) then
    writeln('x inheritsfrom tz');
end.

Birger52

  • Sr. Member
  • ****
  • Posts: 309
Re: Why can't create be overridden
« Reply #14 on: May 17, 2019, 02:33:06 am »
Martin_fr
Quote
Which would explain why the OT wondered about the constructor not using virtual/override, when at the other hand it does use "inherited".
Precisely. It is there, but I'm not allowed to override it.
I did know, I didn't have to, as it does nothing. But still (re)learning and reintroducing myself. Many new things since the beginning.
The lesson in this for me was that constructors must be virtual for derived class to be able to override them.
At least for now - havent investigated the reintroduce yet.

Lazarus 2.0.8 FPC 3.0.4
Win7 64bit
Playing and learning - strictly for my own pleasure.

 

TinyPortal © 2005-2018