<p>Many languages require you to call <code>super</code> before setting your own properties, like in TypeScript:</p>
<pre class="lang-typescript prettyprint-override"><code>class Base {
  public x: number;

  constructor(x: number) {
    this.x = x;
  }
}

class Derived extends Base {
  public y: number;

  constructor(x: number, y: number) {
    // Error to use `this` here, before the `super` call

    super(x);

    this.y = y; // OK (and in fact required)
  }
}
</code></pre>
<p>However, Swift reverses this:</p>
<pre class="lang-swift prettyprint-override"><code>class Base {
  var x: Int

  init(x: Int) {
    self.x = x
  }
}

class Derived: Base {
  var y: Int

  init(x: Int, y: Int) {
    self.y = y // Error to NOT do this here

    super.init(x: x)
  }
}
</code></pre>
<p>What difference does it make, and why would a language enforce one or the other?</p>

<object-oriented><constructors>
Why do languages differ about when `super` must be called in a constructor?
<h2>Computation symmetry on constructors</h2>
<p>Say, you have two classes, <code>MultipleOfTwo</code> and <code>MultipleOfFour</code>. The construct of MultipleOfTwo accepts a number and either succeeds or fails.</p>
<pre><code>def MultipleOfTwo
{
  def __construct( n )
  {
    if ( n % 2 != 0 ) throw new Error();
    this.Number = n;
  }
}
</code></pre>
<p>But your MultipleOfFour <em>cannot</em> have the same functionality:</p>
<pre><code>def MultipleOfFour
{
  def __construct( n )
  {
    this = super(n);                     // First construct Mo2
    if ( n % 4 != 0 ) throw new Error(); // then fails
    // ...
  }
}
</code></pre>
<p>Languages that force <code>super</code> as the first element on a derived class (Java, C#) also force you to create &quot;factories&quot; around this limitation, in an artificial way of separating concerns that in turn creates <em>a lot</em> of duplicating code.</p>

CC BY-SA 4.0
2023-07-05T16:35:47.950Z
2023-07-05T17:02:32.673Z
2023-07-05T17:02:32.673Z
André L F S Bacci
CC BY-SA 4.0
2023-07-05T16:41:05.530Z
Swift and TypeScript mitigate this to an extent by only imposing restrictions on uses of `self`/`this`, and allowing other computations to go wherever. Still, this is a fair point against the way Java does it.
Bbrk24
<p>There is a specific problem that this is trying to solve, which is to prevent code from outside of the constructor from observing an uninitialised object. The issue is that constructors are allowed to call methods on the same class, and those methods aren't supposed to observe an uninitialised object; but those methods can be overridden by subclasses.</p>
<p>Consider the following in Typescript: (<a href="https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G8BQ1XQE4FMwBMD2AdiAJ7QBmeeAXNAQK4C2ARpugNwprCEQAu6dYLzzoAFAEpEnNGl4ALAJYQAdBTzQAvNACsHGTPlLlIPAHMJetAF9p0E+fE0AbngU4p+rjzwhMxs6IABmqa0AAkCIYqalaB4paoNjZIoJAwAELQmAAevJgEODDwyDJYuIQk0Exg6DT0zKwJ0NwEfAJCIhIentAQdAAOrBa2Booq1eihAGxNNjL2Es6u7iU9LRA+fgvBlKERUaqUVgA0VTV7kWPKE7HxtklISASYAO7Q6RJIQA" rel="noreferrer">Playground Link</a>)</p>
<pre class="lang-typescript prettyprint-override"><code>class A {
    readonly foo: number;
    constructor() {
        this.foo = 5;
        this.log();
    }
    log(): void {
        console.log(`foo = ${this.foo}`);
    }
}

class B extends A {
    readonly bar: number;
    constructor() {
        super();
        this.bar = 6;
    }
    log(): void {
        console.log(`foo = ${this.foo}, bar = ${this.bar}`);
    }
}

new B()
// foo = 5, bar = undefined
</code></pre>
<p>In this example, the <code>log</code> method from class <code>B</code> is invoked before the assignment <code>this.bar = 6;</code> in <code>B</code>'s constructor, so the method is able to observe an uninitialised object. This means Typescript's rule ─ that <code>super()</code> must be called before any use of <code>this</code> ─ does not actually solve the problem. Well, it solves part of the problem, but not all of it: it at least means you can't call <code>this.log();</code> in <code>B</code>'s constructor before the <code>super();</code> call.</p>
<p>Java has a stricter version of the same rule: <code>super();</code> must be the first thing in the subclass's constructor. But Java's rule has the same problem. (The equivalent Java code will print <code>0</code> instead of <code>undefined</code>.)</p>
<p>So Swift's rule ─ that subclass fields must be initialised before calling <code>super.init();</code>, and <code>super.init();</code> must be called before any <em>other</em> use of <code>self</code> ─ is better, in the sense that it protects against an uninitialised field being observed outside of the constructor in the class that declares that field.</p>

CC BY-SA 4.0
2023-07-05T02:05:07.190Z
2023-07-05T02:15:30.873Z
2023-07-05T02:15:30.873Z
kaya3
CC BY-SA 4.0
2023-07-05T16:49:17.813Z
In languages that differentiate virtual and final methods, this could be mitigated by disallowing virtual methods in the ctor, right?
Bbrk24
CC BY-SA 4.0
2023-07-05T17:24:51.317Z
@Bbrk24: C++ has another approach - base classes are always initialized first, and calls to virtuals are allowed, but they don't dispatch virtually - it is as if the more derived types don't exist while a base constructor is running (same for destructors). Better explanation here: https://stackoverflow.com/a/962298/635608
Mat
CC BY-SA 4.0
2023-07-06T11:19:29.680Z
@Bbrk24 Yes, at the cost of expressiveness. I think besides backwards compatibility, the reason Java and Typescript allow this is mainly because the language is more useful if you can call methods from constructors, and if that means observing a default initial value (`0`, `null`, `undefined`, etc.) by accident occasionally then that's worth it. It at least doesn't violate memory safety, and there are a few other ways in Java to sneakily observe fields before they are initialised.
kaya3
CC BY-SA 4.0
2023-07-06T11:19:41.110Z
@Mat I think that should be an answer!
kaya3
# Why do languages differ about when `super` must be called in a constructor?
Posted by: username_0 on 2023-07-05
Many languages require you to call super before setting your own properties, like in TypeScript:
class Base {
  public x: number;

  constructor(x: number) {
    this.x = x;
  }
}

class Derived extends Base {
  public y: number;

  constructor(x: number, y: number) {
    // Error to use `this` here, before the `super` call

    super(x);

    this.y = y; // OK (and in fact required)
  }
}

However, Swift reverses this:
class Base {
  var x: Int

  init(x: Int) {
    self.x = x
  }
}

class Derived: Base {
  var y: Int

  init(x: Int, y: Int) {
    self.y = y // Error to NOT do this here

    super.init(x: x)
  }
}

What difference does it make, and why would a language enforce one or the other?
**Tags:** object-oriented constructors
---
## 2 answers
### Answer by username_2 on 2023-07-05. Score: 8
There is a specific problem that this is trying to solve, which is to prevent code from outside of the constructor from observing an uninitialised object. The issue is that constructors are allowed to call methods on the same class, and those methods aren't supposed to observe an uninitialised object; but those methods can be overridden by subclasses.
Consider the following in Typescript: (Playground Link)
class A {
    readonly foo: number;
    constructor() {
        this.foo = 5;
        this.log();
    }
    log(): void {
        console.log(`foo = ${this.foo}`);
    }
}

class B extends A {
    readonly bar: number;
    constructor() {
        super();
        this.bar = 6;
    }
    log(): void {
        console.log(`foo = ${this.foo}, bar = ${this.bar}`);
    }
}

new B()
// foo = 5, bar = undefined

In this example, the log method from class B is invoked before the assignment this.bar = 6; in B's constructor, so the method is able to observe an uninitialised object. This means Typescript's rule ─ that super() must be called before any use of this ─ does not actually solve the problem. Well, it solves part of the problem, but not all of it: it at least means you can't call this.log(); in B's constructor before the super(); call.
Java has a stricter version of the same rule: super(); must be the first thing in the subclass's constructor. But Java's rule has the same problem. (The equivalent Java code will print 0 instead of undefined.)
So Swift's rule ─ that subclass fields must be initialised before calling super.init();, and super.init(); must be called before any other use of self ─ is better, in the sense that it protects against an uninitialised field being observed outside of the constructor in the class that declares that field.
> **Comments:**
> **username_0** (2023-07-05): In languages that differentiate virtual and final methods, this could be mitigated by disallowing virtual methods in the ctor, right?  
> **username_3** (2023-07-05): @Bbrk24: C++ has another approach - base classes are always initialized first, and calls to virtuals are allowed, but they don't dispatch virtually - it is as if the more derived types don't exist while a base constructor is running (same for destructors). Better explanation here: https://stackoverflow.com/a/962298/635608  
> **username_2** (2023-07-06): @Bbrk24 Yes, at the cost of expressiveness. I think besides backwards compatibility, the reason Java and Typescript allow this is mainly because the language is more useful if you can call methods from constructors, and if that means observing a default initial value (`0`, `null`, `undefined`, etc.) by accident occasionally then that's worth it. It at least doesn't violate memory safety, and there are a few other ways in Java to sneakily observe fields before they are initialised.  
> **username_2** (2023-07-06): @Mat I think that should be an answer!  
---
### Answer by username_1 on 2023-07-05. Score: 1
Computation symmetry on constructors
Say, you have two classes, MultipleOfTwo and MultipleOfFour. The construct of MultipleOfTwo accepts a number and either succeeds or fails.
def MultipleOfTwo
{
  def __construct( n )
  {
    if ( n % 2 != 0 ) throw new Error();
    this.Number = n;
  }
}

But your MultipleOfFour cannot have the same functionality:
def MultipleOfFour
{
  def __construct( n )
  {
    this = super(n);                     // First construct Mo2
    if ( n % 4 != 0 ) throw new Error(); // then fails
    // ...
  }
}

Languages that force super as the first element on a derived class (Java, C#) also force you to create "factories" around this limitation, in an artificial way of separating concerns that in turn creates a lot of duplicating code.
> **Comments:**
> **username_0** (2023-07-05): Swift and TypeScript mitigate this to an extent by only imposing restrictions on uses of `self`/`this`, and allowing other computations to go wherever. Still, this is a fair point against the way Java does it.  
---
