Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Dúvida com o private

Guilherme, nao entendi o seguinte: voce colocou o modificador private no set da propriedade CPF, da classe Funcionario. No construtor da mesma é feita a inicializacao do CPF. Nao entendo como o código compila se o campo é private e a classe Diretor consegue fazer a inicializacao também do CPF.

insira seu código aqui
6 respostas

Boa noite, Janile! Como vai?

Eu não sou o Guilherme, mas posso te ajudar! O private na propriedade serve para impedir de alterar o valor dessa propriedade após o objeto ter sido criado. Ou seja, uma vez que vc tenha criado um objeto com o CPF X, esse valor não poderá ser alterado! Mas o construtor continua podendo receber um CPF como parâmetro.

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos!

Oi Gabriel! Obg pela resposta...mas continuo sem entender porque a classe filha conseguiu alterar o CPF, se o set é private, portanto somente a classe base deveria conseguiria fazer essa inicializacao.

Olá, Janile. Tudo bom?

A classe derivada não alterou o CPF da classe base!

Quando temos uma classe sem construtor padrão (aquele sem argumentos) somos sempre obrigados a preencher o argumento durante a criação de uma nova instância. Com a classe abaixo, por exemplo:

class ClasseBase
{
    public ClasseBase(string argumento)
    {
        //...
    }
}

Podemos criar instâncias apenas preenchendo o argumento. new ClasseBase("valor1"), new ClasseBase(null), etc.

Como fica quando derivamos desta classe?

class ClasseDerivada : ClasseBase
{
    public ClasseDerivada()
    {
        //...
    }
}

O código de ClasseDerivada não compila. Porque, para criar um objeto do tipo ClasseDerivada é necessário antes executar o construtor de ClasseBase. Para executar este segundo construtor, é necessário preencher o argumento. Então, no construtor, usamos a sintaxe:

public ClasseDerivada() : base("valor do argumento")
{
    //...
}

Neste exemplo, não criei propriedades ou campos na ClasseBase. Só lidei com seu construtor!

Na classe Funcionario, usamos o argumento para definir o valor da propriedade de setter privado. Mas, quem faz isto é Funcionario e não a classe derivada.

O que acha? Esclareci sua dúvida?

Abs.

Guilhermel, ainda nao consegui entender. Quando tenho a classe base Funcionario, com o set da propriedade CPF private, e um construtor que recebe como argumento uma string cpf que vai inicializar a propriedade CPF, porque o codigo compila se quando instancio um objeto do tipo Diretor, que também passa através do argumento do construtor uma string cpf, consegue settear a propriedade CPF que é private. Acho que estou confundindo o conceito de Heranca. Quando uma classe é derivada, ela herda todos os membros da classe base, mas esses membros que herdam nao sao proprios?

solução!

Quando uma classe deriva de outra, ela herda todos os membros, até aqueles marcados com private na classe base e que, portanto, não são diretamente acessíveis na classe derivada.

Vamos pensar em uma situação mais simples:

class Funcionario
{
    private string _cpf;

    public void DefinirCPF(string novoCPF)
    {
        _cpf = novoCPF;
    }
}

Aqui, a classe Funcionario define o membro privado _cpf e, só pra reforçar, sabemos que o código abaixo não compila:

Funcionario func = new Funcionario();
func._cpf = "342.545.235-39";

Porque _cpf é acessível somente dentro da classe Funcionario. Mas, esta classe possui o método DefinirCPF que é público e, portanto, acessível fora da classe Funcionario.

Agora, vamos usar um caso de herança:

class Diretor : Funcionario
{
}

A classe Diretor possui o membro _cpf também! Mas, este é inacessível, então o código com construtor abaixo não compila:

class Diretor : Funcionario
{
    public Diretor()
    {
        _cpf = "342.545.235-39";
    }
}

Contudo, a classe Diretor também possui o método público DefinirCPF. Então realizar uma chamada a este método é permitido:

class Diretor : Funcionario
{
    public Diretor()
    {
        DefinirCPF("342.545.235-39");
    }
}

A implementação de DefinirCPF foi definida na classe base Funcionario. Do ponto de vista do Diretor, a implementação na classe base não importa. O importante é que este é um método público que pode ser invocado. Assim como no exemplo abaixo:

static void Main(string[] args)
{
    Funcionario func = new Funcionario();
    func.DefinirCPF("342.545.235-39");
}

A implementação em DefinirCPF é omitida do método Main e a classe Program não precisa ter acesso aos membros que este método usa, pois isto é responsabilidade de Funcionario.

Aqui, acontece a mesma coisa:

public Diretor()
{
    DefinirCPF("342.545.235-39");
}

Beleza? O que você acha disto até agora?

Agora, vamos remover o método DefinirCPF da classe Funcionario e colocar este código dentro do construtor:

class Funcionario
{
    private string _cpf;

    public Funcionario(string cpf)
    {
        _cpf = cpf;
    }
}

Agora, só podemos criar uma instância de Funcionario preenchendo este argumento e as classes derivadas precisam preencher este argumento também, através da palavra reservada base no construtor:

class Diretor : Funcionario
{
    public Diretor() : base("342.545.235-39")
    {
    }
}

E aqui, novamente, não escrevemos nenhum código na classe Diretor que acessa o campo privado _cpf e define a ele um valor. Quem faz isto é o construtor definido em Funcionario.

As regras que vimos acima com chamadas de métodos valem aqui também! A implementação deste construtor é omitida a classe derivada Diretor, somente a classe Funcionario a conhece e, portanto, pode acessar seus membros privados.

O que você acha? Se você continuar com dúvida, poderia dar um exemplo de código e pontuar as linhas que te trazem dúvidas sobre o comportamento ou o que não deveria compilar?

Ficamos no aguardo. Abs.

Guilhermeeeeee, voce é um genio! Obrigado pela predisposicao!