Как получить доступ к закрытой переменной экземпляра из защищенного метода в TypeScript - PullRequest
0 голосов
/ 25 августа 2018

У меня есть абстрактный класс с абстрактным методом, который реализуется дочерним классом.Реализованный метод в дочернем классе должен обновить личную переменную экземпляра дочернего класса.После этого я хочу получить значение закрытой переменной с помощью метода get.

Чтобы увидеть проблему в действии, я создал пример кода на детской площадке .

* 1006.* Animal - это базовый класс с абстрактным методом someAbstractMethod () :
abstract class Animal {

    protected abstract someAbstractMethod(): void;

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

Snake наследуется от Animal и реализует абстрактный метод someAbstractMethod () .Этот класс имеет метод получения / установки для извлечения значения переменной частного экземпляра 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)
    }
}

Сначала создайте новый Snake, а затем получите значение переменной частного экземпляра с помощьювызов геттера для sam.someValue :

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

Неожиданный результат

Печатный журнал:

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

sam.someValue возвращает 'начальное значение' , но на самом деле метод someAbstractMethod () был вызван раньше и должен был установить значение ', теперь установлен начто-то новое '

1 Ответ

0 голосов
/ 25 августа 2018

Прочитав этот связанный вопрос , я нашел ответ на свой вопрос.

Мое решение

Единственное изменение было в классе Змея . Я удалил присвоение переменной 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";
    }
}

Обновлен код на детской площадке

Проблема заключалась в том, что инициализация someLocalVariable выполняется ПОСЛЕ вызова конструктора. someAbstractMethod () вызывается из super.constructor и фактически корректно устанавливает значение, НО затем возвращается из конструктора, и после этого приватная переменная экземпляра инициализируется "начальным значением" . При удалении присвоения значение someLocalVariable остается неизменным после возврата из ctor.

Но в этом решении все еще что-то не так, потому что, если включены опции компилятора --strictPropertyInitialization и --strictNullChecks, компиляция завершится неудачно. Для меня этот факт в настоящее время нормальный, но мне кажется, что я делаю что-то не так.

...