1

I have an abstract class with an abstract method that is implemented by the child class. The implemented method in the child class should update an private instance variable of the child class. After this I want to retrieve the value of the private variable by using a getter method.

To see the problem in action I have created some sample code in playground.

Animal is the base class with the abstract method someAbstractMethod():

abstract class Animal {

    protected abstract someAbstractMethod(): void;

    constructor() {
        document.writeln("A new animal is born<br>");
        this.someAbstractMethod();                          //  <-- call into child class
    }  
}

Snake inherits from Animal and implements the abstract method someAbstractMethod(). This class has a getter/setter to retrieve the value of the private instance variable someLocalVariable:

class Snake extends Animal {

    private someLocalVariable: string = "intial value";

    constructor() {
        super();
    }

    get someValue() {
        document.writeln("Called getter for someValue<br>");
        return this.someLocalVariable;
   }

    set someValue(value: string) {
        document.writeln("Called setter for someValue<br>");
        this.someLocalVariable = value;
    }

    protected someAbstractMethod() {
        document.writeln("Called someAbstractMethod()<br>");
        this.someLocalVariable = "now set to something new";        //   <-- instance variable not updated (or in another scope)
    }
}

First create a new Snake and then get the value of the private instance variable by using a getter call to sam.someValue:

let sam = new Snake();
document.writeln("Value of someValue: " + sam.someValue);   

Unexpected Result

Printed Log:

    A new animal is born
    Called someAbstractMethod()
    Called getter for someValue
    Value of someValue: intial value

sam.someValue returns 'initial value', but actually the method someAbstractMethod() was called before and should have set the value to 'now set to something new'

ElrondMcBong
  • 21
  • 1
  • 6
  • Duplicate of https://stackoverflow.com/questions/43595943/why-are-derived-class-property-values-not-seen-in-the-base-class-constructor/43595944#43595944 – Ryan Cavanaugh Aug 24 '18 at 23:41
  • Possible duplicate of [Why are derived class property values not seen in the base class constructor?](https://stackoverflow.com/questions/43595943/why-are-derived-class-property-values-not-seen-in-the-base-class-constructor) – Matt McCutchen Aug 25 '18 at 01:00
  • The question looks different but related. The very detailed answer there did help me to understand how it behaves and why it behaves like this. With that answer, I did solve my issue. Thanks! – ElrondMcBong Aug 25 '18 at 17:59

1 Answers1

0

After reading this related question, I found an answer to my question.

My solution

The only change was in class Snake. I have removed the assignment to the variable someLocalVariable.

class Snake extends Animal {

    private someLocalVariable: string; // = "intial value";         <--- remove assignment

    constructor() {
        super();
    }

    get someValue() {
        document.writeln("Called getter for someValue<br>");
        return this.someLocalVariable;
    }

    set someValue(value: string) {
        document.writeln("Called setter for someValue<br>");
        this.someLocalVariable = value;
    }

    protected someAbstractMethod() {
        document.writeln("Called someAbstractMethod()<br>");
        this.someLocalVariable = "now set to something new";
    }
}

Updated code in playground

The problem was that the initialization of someLocalVariable is done AFTER the constructor call. someAbstractMethod() is called from the super.constructor and actually it sets the value correctly, BUT then it returns from the constructor and after this the private instance variable is initialized with "inital value". By removing the assignment, the value of someLocalVariable stays unchanged after returning from ctor.

But there is still something wrong with this solution, because if the compiler options --strictPropertyInitialization and --strictNullChecks are enabled, then the compilation fails. For me this fact is ok at the moment, but it feels like I am doing something wrong.

ElrondMcBong
  • 21
  • 1
  • 6