Syntaxerror: Private field '#attribute' must be declared in an enclosing class

Asked

Viewed 932 times

1

I created the Employee and Director classes, being Employee Inheritor Manager(daughter), but when instantiating a Director object I got the following error: Syntaxerror: Private field '#bonus' must be declared in an enclosing class.

Replaces the "#" used in private attributes with "_" and it worked. Are private attributes with "#" not inherited? Someone knows the reason why it doesn’t work?

NOTE: I am using Node.js v.14.2.0 to interpret the code.

Below are the classes in question:

// index.js
import { Funcionario } from "./funcionario/Funcionario.js";
import { Gerente } from "./funcionario/Gerente.js";
import { Diretor } from "./funcionario/Diretor.js";

const diretor = new Diretor(11122233345, "Roberto", 2000);

export class Funcionario {
    #bonificacao = 1;
    #cpf;
    #nome;
    #salario;
    #senha;

    constructor(cpf, nome, salario) {
        this.#cpf = cpf;
        this.#nome = nome;
        this.#salario = salario;
        if (this.constructor == Funcionario)
            throw new Error(
                "Não é permitida a instanciação da classe Funcionario diretamente."
            );
    }

    get senha() {
        return this.#senha;
    }

    cadastrarSenha(senha) {
        this.#senha = senha;
    }
}

import { Funcionario } from "./Funcionario.js";

export class Diretor extends Funcionario {
    constructor(cpf, nome, salario) {
        super(cpf, nome, salario);
        this.#bonificacao = 2;
    }
}

1 answer

1

The classic confusion between inheritance and private vs protected properties.

The Functionario class has the field #bonificacao as private, this means that only the internal code of that same class has access to it.

The Director class that is extending the Employee class does not have access to this field because it is not protected and yes private.

But it is not the end of the world, if you declare the field again in the daughter class (as in the code below) everything will work.

You can run the code here in the Browser by clicking the blue button Execute just below the code

class Funcionario {
    #bonificacao = 1;
    #cpf;
    #nome;
    #salario;
    #senha;

    constructor(cpf, nome, salario) {
        this.#cpf = cpf;
        this.#nome = nome;
        this.#salario = salario;
        if (this.constructor == Funcionario)
            throw new Error(
                "Não é permitida a instanciação da classe Funcionario diretamente."
            );
    }

    get senha() {
        return this.#senha;
    }

    cadastrarSenha(senha) {
        this.#senha = senha;
    }
}

class Diretor extends Funcionario {
    #bonificacao;
    constructor(cpf, nome, salario) {
        super(cpf, nome, salario);
        this.#bonificacao = 2;
    }
    
    get bonificacao () { return this.#bonificacao }
}

const diretor = new Diretor('123.123.123.123', 'Daniel', 150_000)

console.log(diretor.bonificacao)

  • Thanks for the help. But I want Director.js to inherit the bonus variable from Funcionario.js, thus, if there is no "this. #bonus = 2", I want the default value to be the one set in the mother class. If I set #bonus in Director.js, the value will be Undefined. Is there a prefix that determines that a variable is protected, just as # determines that the variable is private? Otherwise, I should use as the default prefix "_" leaving the public variables and using encapsulation for their protection, or is there some other way around it?

  • Private Attributes/Fields is a new Feature, and for many years devs had to simulate this feature. Unfortunately, in your case, there is no way to declare protected Fields.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.