title: Delphi: Understanding constructors
body: <p>i'm looking to <em>understand</em></p>
  
  <ul>
  <li>virtual</li>
  <li>override</li>
  <li>overload</li>
  <li>reintroduce</li>
  </ul>
  
  <p>when applied to object constructors. Every time i randomly add keywords until the compiler shuts up - and (after 12 years of developing with Delphi) i'd rather know what i'm doing, rather than trying things randomly.</p>
  
  <p>Given a hypothetical set of objects:</p>
  
  <pre><code>TComputer = class(TObject)
  public
      constructor Create(Cup: Integer); virtual;
  end;
  
  TCellPhone = class(TComputer)
  public
      constructor Create(Cup: Integer; Teapot: string); virtual;
  end;
  
  TiPhone = class(TCellPhone)
  public
      constructor Create(Cup: Integer); override;
      constructor Create(Cup: Integer; Teapot: string); override;
  end;
  </code></pre>
  
  <p>The way i want them to behave is probably obvious from the declarations, but:</p>
  
  <ul>
  <li><code>TComputer</code> has the simple constructor, and descendants can override it</li>
  <li><code>TCellPhone</code> has an alternate constructor, and descendants can override it</li>
  <li><code>TiPhone</code> overrides both constructors, calling the inherited version of each</li>
  </ul>
  
  <p>Now that code doesn't compile. i want to understand <em>why</em> it doesn't work. i also want to understand the proper way to override constructors. Or perhaps you could never override constructors? Or perhaps it is perfectly acceptable to override constructors? Perhaps you should never have multiple constructors, perhaps it is perfectly acceptable to have multiple constructors.</p>
  
  <p>i want to understand the <em>why</em>. Fixing it would then be obvious.</p>
  
  <h2>See also</h2>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/3874330/delphi-how-to-hide-ancestor-constructors">Delphi: How to hide ancestor constructors?</a></li>
  <li><a href="https://stackoverflow.com/questions/53806/reintroducing-functions-in-delphi">Reintroducing functions in Delphi</a></li>
  <li><a href="https://stackoverflow.com/questions/3876484/delphi-how-to-add-a-different-constructor-to-a-descendant">Delphi: How to add a different constructor to a descendant?</a></li>
  </ul>
  
  <p><strong>Edit:</strong> i'm also looking to get some reasoning on the order of <code>virtual</code>, <code>override</code>, <code>overload</code>, <code>reintroduce</code>. Because when trying all combinations of keywords, the number of combinations explodes:</p>
  
  <ul>
  <li>virtual; overload;</li>
  <li>virtual; override;</li>
  <li>override; overload;</li>
  <li>override; virtual;</li>
  <li>virtual; override; overload;</li>
  <li>virtual; overload; override;</li>
  <li>overload; virtual; override;</li>
  <li>override; virtual; overload;</li>
  <li>override; overload; virtual;</li>
  <li>overload; override; virtual;</li>
  <li>etc</li>
  </ul>
  
  <p><strong>Edit 2:</strong> i guess we should begin with "<em>is the object hierarchy given even possible?</em>" If not, why not? For example, is it fundamentally incorrect to have a constructor from an ancestor?</p>
  
  <pre><code>TComputer = class(TObject)
  public
      constructor Create(Cup: Integer); virtual;
  end;
  
  TCellPhone = class(TComputer)
  public
      constructor Create(Cup: Integer; Teapot: string); virtual;
  end;
  </code></pre>
  
  <p>i would expect that <code>TCellPhone</code> now has two constructors. But i can't find the combination of keywords in Delphi to make it think that's a valid thing to do. Am i fundamentally wrong in thinking i can have two constructors here in <code>TCellPhone</code>?</p>
  
  <hr>
  
  <blockquote>
    <p><strong>Note:</strong> Everything below this line is not strictly needed to answer the
    question - but it does help to explain
    my thinking. Perhaps you can see,
    based on my thought processes, what
    fundamental piece i'm missing that
    makes everything clear.</p>
  </blockquote>
  
  <p>Now these declarations don't compile:</p>
  
  <pre><code>//Method Create hides virtual method of base type TComputer:
  TCellPhone = class(TComputer)
     constructor Create(Cup: Integer; Teapot: string);  virtual;
  
  //Method Create hides virtual method of base type TCellPhone:
  TiPhone = class(TCellPhone)
  public
     constructor Create(Cup: Integer); override;
     constructor Create(Cup: Integer; Teapot: string); overload;  &lt;--------
  end;
  </code></pre>
  
  <hr>
  
  <p>So first i'll trying fixing <code>TCellPhone</code>. i'll start by randomly adding the <code>overload</code> keyword (i know i don't want <code>reintroduce</code> because that would hide the other constructor, which i don't want):</p>
  
  <pre><code>TCellPhone = class(TComputer)
  public
     constructor Create(Cup: Integer; Teapot: string); virtual; overload;
  end;
  </code></pre>
  
  <p>But that fails: <code>Field definition not allowed after methods or properties</code>.</p>
  
  <p>i know from experience that, even though i don't have a field after a method or property, if i reverse the order of the <code>virtual</code> and <code>overload</code> keywords: Delphi will shut up:</p>
  
  <pre><code>TCellPhone = class(TComputer)
  public
     constructor Create(Cup: Integer; Teapot: string); overload; virtual; 
  end;
  </code></pre>
  
  <p>But i still get the error:</p>
  
  <blockquote>
    <p>Method 'Create' hides virtual method of base type 'TComputer'</p>
  </blockquote>
  
  <p>So i try removing both keywords:</p>
  
  <pre><code>TCellPhone = class(TComputer)
  public
     constructor Create(Cup: Integer; Teapot: string);
  end;
  </code></pre>
  
  <p>But i still get the error:</p>
  
  <blockquote>
    <p>Method 'Create' hides virtual method of base type 'TComputer'</p>
  </blockquote>
  
  <p>So i resign myself to now trying <code>reintroduce</code>:</p>
  
  <pre><code>TCellPhone = class(TComputer)
  public
     constructor Create(Cup: Integer; Teapot: string); reintroduce;
  end;
  </code></pre>
  
  <p>And now TCellPhone compiles, but it has made things much worse for TiPhone:</p>
  
  <pre><code>TiPhone = class(TCellPhone)
  public
     constructor Create(Cup: Integer); override; &lt;-----cannot override a static method
     constructor Create(Cup: Integer; Teapot: string); override; &lt;-----cannot override a static method
  end;
  </code></pre>
  
  <p>Both are complaining that i cannot override them, so i remove the <code>override</code> keyword:</p>
  
  <pre><code>TiPhone = class(TCellPhone)
  public
     constructor Create(Cup: Integer);
     constructor Create(Cup: Integer; Teapot: string);
  end;
  </code></pre>
  
  <p>But now the 2nd create says it must be marked with overload, which i do (in fact i'll mark both as overload, since i know what will happen if i don't):</p>
  
  <pre><code>TiPhone = class(TCellPhone)
  public
     constructor Create(Cup: Integer); overload;
     constructor Create(Cup: Integer; Teapot: string); overload;
  end;
  </code></pre>
  
  <p>All all is good in the <code>interface</code> section. Unfortunately my implementations won't work. My single parameter constructor of TiPhone cannot call the inherited constructor:</p>
  
  <pre><code>constructor TiPhone.Create(Cup: Integer);
  begin
      inherited Create(Cup); &lt;---- Not enough actual parameters
  end;
  </code></pre>