Por que precisamos de variáveis ​​privadas?


210

Por que precisamos de variáveis ​​privadas nas classes?

Todo livro sobre programação que li diz que essa é uma variável privada, é assim que você a define, mas pára por aí.

A redação dessas explicações sempre me pareceu realmente ter uma crise de confiança em nossa profissão. As explicações sempre soaram como outros programadores que estão tentando bagunçar nosso código. No entanto, existem muitas linguagens de programação que não possuem variáveis ​​privadas.

  1. O que as variáveis ​​privadas ajudam a impedir?

  2. Como você decide se uma propriedade específica deve ser privada ou não? Se, por padrão, todos os campos DEVEM ser privados, por que existem membros de dados públicos em uma classe?

  3. Em que circunstâncias uma variável deve ser tornada pública?


9
Sua pergunta parece muito independente de idioma, mas você a marcou como java e c ++. Se você estiver interessado em perspectivas de fora desses dois idiomas, provavelmente deve dizer isso.
James

8
Para o registro, a criação de um método privado não aumenta a "segurança". Outras partes do seu aplicativo ainda podem acessar membros particulares usando reflexão.
kba

3
O uso e a diferença de variáveis ​​privadas e públicas, e por que as temos, só podem ser entendidos no contexto de princípios gerais orientados a objetos. Não pode ser entendido separadamente. Você provavelmente precisa olhar para essa perspectiva, as coisas podem ficar mais claras.
Nazar Merza


3
Se você pegar alguém usando cinto de segurança em seu carro, deve tirar a carteira de motorista, pois obviamente eles não confiam em suas próprias habilidades para dirigir.
gnasher729

Respostas:


307

Não se trata tanto de confiança, mas de gerenciar a complexidade.

Um membro público pode ser acessado de fora da classe, o que por considerações práticas significa "potencialmente em qualquer lugar". Se algo der errado com um campo público, o culpado pode estar em qualquer lugar; portanto, para rastrear o bug, talvez seja necessário analisar bastante código.

Um membro privado, por outro lado, só pode ser acessado de dentro da mesma classe; portanto, se algo der errado com isso, geralmente haverá apenas um arquivo de origem para examinar. Se você possui um milhão de linhas de código em seu projeto, mas suas classes são mantidas pequenas, isso pode reduzir seu esforço de rastreamento de bugs em um fator de 1000.

Outra vantagem está relacionada ao conceito de 'acoplamento'. Um membro do público mde uma classe Aque é usado por outra classe Bintroduz uma dependência: se você mudar mem A, você também tem que verificar usos de mno B. Pior ainda, nada na classe Ainforma onde mestá sendo usado; então, novamente, você precisa pesquisar em toda a base de código; se é uma biblioteca que você está escrevendo, você precisa garantir o código foraseu projeto não falha por causa de sua alteração. Na prática, as bibliotecas tendem a permanecer com suas assinaturas de métodos originais o maior tempo possível, não importa o quão doloroso, e depois introduzir um bloco de alterações quebradas com uma atualização de versão principal. Com os membros privados, por outro lado, você pode excluir dependências imediatamente - elas não podem ser acessadas de fora, portanto todas as dependências estão contidas na classe.

Nesse contexto, "outros programadores" incluem seu futuro e o passado. Provavelmente, você sabe agora que não deve fazer essa coisa X com sua variável Y, mas você deve ter esquecido três meses depois, quando um cliente precisa urgentemente que você implemente algum recurso, e você se pergunta por que fazer X quebra Y de maneiras obscuras.

Portanto, quando você deve tornar as coisas privadas: eu diria que tornar tudo privado por padrão e depois expõe apenas as partes que absolutamente precisam ser públicas. Quanto mais você puder tornar privado, melhor.


24
+1 para chegar ao cerne da questão, embora eu pessoalmente tenha achado meu código mais fácil de manter quando parei de passar por aros apenas para garantir que uma variável frequentemente usada permaneça privada. Claro que um erro pode surgir no futuro, mas é 60 menos linhas de código para peneirar e menos variáveis e funções para arrancar;)
Jeffrey Sweeney

48
O Santo Graal da computação moderna está mantendo a complexidade baixa.

11
Eu sempre gosto de dizer que parte da depuração não é apenas direcionar diretamente para "o que deu errado", mas tomar o processo rotativo de descobrir "o que não deu errado" e concentrar minha investigação no que resta. Se eu conseguir que o compilador me ajude com ferramentas como variáveis ​​privadas para definir "o que não pode ter ocorrido", isso me poupará muito tempo. Somente nos raros casos em que provo que o que deu errado não pode ter ocorrido, tenho que me aprofundar nas suposições mais assustadoras, como talvez uma saturação de buffer substituindo meus dados privados.
Cort Ammon

2
Exatamente isso. Quando as pessoas ouvem "ocultação de informações", eles pensam que eles devem usar variáveis privadas para coisas como chaves de criptografia, credenciais de banco de dados, etc.
Wayne Werner

2
@AdamZerner, consulte "Diga, não pergunte" ( martinfowler.com/bliki/TellDontAsk.html ) sobre ter getters / setters em primeiro lugar - mas, caso contrário, sim, porque você deve estar livre para alterar a representação interna do valor a qualquer momento você deseja. Como sempre, há exceções ... (por exemplo, DTOs)
doubleYou

111

Variáveis ​​privadas ajudam a impedir que as pessoas dependam de certas partes do seu código. Por exemplo, digamos que você queira implementar alguma estrutura de dados. Você deseja que os usuários da sua estrutura de dados não se importem com a forma como a implementou, mas apenas utilizem a implementação por meio de sua interface bem definida. O motivo é que, se ninguém depender da sua implementação, você poderá alterá-la quando quiser. Por exemplo, você pode alterar a implementação de back-end para melhorar o desempenho. Quaisquer outros desenvolvedores que dependem de suas implementações serão interrompidos, enquanto os usuários da interface ficarão bem. Ter a flexibilidade de alterar implementações sem afetar os usuários da classe é um grande benefício que o uso de variáveis ​​privadas (e de forma mais abrangente, encapsulamento ) oferece a você.

Além disso, não é realmente uma "crise de confiança". Se você tornar público um dado, não poderá garantir que ninguém dependa dele. Muitas vezes, é muito conveniente depender de alguma variável específica da implementação, em vez de passar pela interface pública, especialmente no calor de um prazo. Além disso, os desenvolvedores nem sempre percebem que dependem de algo que pode mudar.

Portanto, esse tipo de resposta a suas outras perguntas, espero. Todos os detalhes de sua implementação devem ser privados e a parte pública deve ser uma interface pequena, concisa e bem definida para o uso de sua classe.


24
A IMO também trata da comunicação entre o autor da lib e o consumidor da lib. A interface pública é do tipo "use this" e o privates é do tipo "não use isso", exceto que em Java, você realmente não pode usá-lo por acidente, se o tornar privado, para que seja mais seguro e claro dessa maneira.
chakrit

5
@chakrit e outros: Observe que aqueles que realmente desejam usar seus campos e métodos particulares podem fazê-lo (via reflexão). privateé menor que "não se destina principalmente à segurança", não fornece "segurança" para falar. É apenas uma dica forte (fornecida pelo compilador) para não acessá-lo.

@ delnan observe a frase "por acidente", sim, talvez eu deva ser mais claro sobre isso.
chakrit

@chakrit Sim, eu não quis dizer que você estava errado. Eu só queria promover esse ponto.

11
@ delnan: campos particulares, em alguns idiomas, fornecem certas formas de segurança. Por exemplo, consulte a resposta de Eric Lippert para Os níveis e modificadores de acesso (privado, lacrado etc.) servem para fins de segurança em C #? .
27713 Brian

25

A palavra-chave aqui é Encapsulamento . No OOP, você deseja usar variáveis ​​privadas para impor o encapsulamento adequado de seus objetos / classes.

Embora outros programadores não estejam buscando você, eles interagem com seu código. Se você não tornar uma variável privada, ela poderá se referir a ela em seu próprio código, sem querer causar nenhum dano. No entanto, se você precisar voltar para a aula e mudar alguma coisa, não saberá mais quem usa qual variável e onde. O objetivo do encapsulamento é tornar explícita a interface externa da classe, para que você saiba que apenas esses métodos (normalmente) poderiam ter sido usados ​​por outras pessoas.

  1. Portanto, variáveis ​​privadas garantem que a variável correspondente permaneça apenas na classe de definição. Se você precisar alterá-lo, a alteração será local para a própria classe.

  2. Em linguagens tradicionais como C ++ ou Java, você geralmente torna tudo privado e acessível apenas pelos getters e setters correspondentes. Não há necessidade de decidir muito realmente.

  3. Às vezes, f.ex. em uma estrutura C ++, você precisa de uma classe apenas como uma maneira de agrupar várias coisas. Por exemplo, considere uma classe Vector que possua apenas xum yatributo e. Nesses casos, você pode permitir acesso direto a esses atributos declarando-os públicos. Em particular, você não deve se importar se algum código externo modifica um objeto da sua classe escrevendo diretamente novos valores em xou y.

Como um ponto adicional, observe que esse assunto é considerado um pouco diferente em outros idiomas. Por exemplo, linguagens fortemente enraizadas na programação funcional enfatizam a imutabilidade dos dados, ou seja, os valores dos dados não podem ser alterados. Nesses casos, você não precisa se preocupar com o que outros programadores (ou o código deles) fazem com seus dados. Eles simplesmente não podem fazer nada que possa afetar seu código, porque todos os dados são imutáveis.

Nessas linguagens, você obtém algo chamado princípio de acesso uniforme , onde deliberadamente não distingue métodos como getters e setters, mas fornece acesso direto à variável / função. Então, você pode dizer que as declarações privadas são muito mais populares nos cenários orientados a objetos.

Isso também mostra como a ampliação de seu conhecimento para incluir outros campos faz com que você visualize os conceitos existentes de uma maneira totalmente nova.


11
+1 "Embora outros programadores não estejam buscando você, eles interagem com seu código." Programadores que usam seu código não são inerentemente ruins. Ao usar variáveis ​​privadas, você garante que elas (e você, no futuro) não sejam prejudicadas usando o código. Também ajuda a projetar uma API melhor e documentá-la.
Szalski 05/10

7

Variáveis ​​privadas garantem que referências posteriores fora do escopo de um objeto ou função não afetem inadvertidamente outras variáveis. Para grandes projetos de programação, isso pode ajudar a evitar muitos problemas interessantes (que geralmente não são detectados pelo compilador).

Por exemplo, linguagens prototípicas como o Javascript podem permitir que os usuários pesquisem variáveis ​​conforme entenderem:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

Se essa variável fosse privada, não poderia ser alterada de fora:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

Dito isto, nem todas as variáveis ​​precisam ser privadas e o uso excessivo de variáveis ​​privadas pode realmente tornar o código mais complicado. Campos triviais que não afetam seriamente um objeto não precisam de métodos get()e set()métodos.

As variáveis ​​privadas também facilitam a expansão do código no futuro, sem depender de documentação pesada sobre o que as muitas variáveis ​​públicas fazem. Existe menos risco de quebrar acidentalmente a funcionalidade se menos variáveis ​​puderem ser substituídas.

Variáveis ​​públicas devem ser usadas quando um objeto / função acessa outros objetos / funções, pois, como regra, variáveis ​​privadas não podem fazer isso. Você pode ter de algumas a várias variáveis ​​públicas, e não é ruim usá-las se elas forem usadas corretamente.


Não é óbvio por que alertar 3 seria um "uh oh!" nesse caso. Talvez seja isso que o programador quisesse que acontecesse.
immibis

@immibis Talvez, e talvez eu devesse ter elaborado mais a resposta. Mas o acesso às propriedades pode abrir a porta por violar alguns princípios de POO, como princípio aberto-fechado ou LoD, pois você potencialmente está expondo os detalhes da implementação. Claro que ao seu ponto, depende de qual é exatamente a propriedade. A maioria das linguagens usa objetos como referências, e quando referências de objetos são passadas e outros devs alteram silenciosamente as propriedades, pode ser MUITO difícil depurar. Na IMO, é muito mais fácil e extensível trabalhar com métodos se você tiver uma instância de classe.
Jeffrey Sweeney

7

Existem algumas boas respostas citando os benefícios para futuros mantenedores e usuários de uma classe. No entanto, também existem benefícios para o design original. Ele fornece um ponto de demarcação claro entre quando seu objetivo é facilitar as coisas para si mesmo e quando seu objetivo é facilitar as coisas para o usuário da classe. Quando você escolhe entre público e privado, ele sinaliza para o seu cérebro mudar para um modo ou outro, e você acaba com uma API melhor.

Não é que idiomas sem privacidade tornem esse design impossível, apenas menos provável. Em vez de ser solicitado a escrever algo como foo.getBar(), as pessoas tendem a pensar que um getter não é necessário, porque é mais fácil escrever foo.bar, mas essa decisão não é revisitada quando você acaba com monstruosidades mais longas obj.container[baz].foo.bar. Programadores que nunca trabalharam em uma linguagem mais rígida podem nem perceber o que há de errado nisso.

É por isso que em idiomas sem privacidade, as pessoas geralmente adotam padrões de nomes que simulam isso, como acrescentar um sublinhado a todos os membros "particulares". É um sinal útil, mesmo quando o idioma não o aplica.


3

Todas as variáveis ​​devem ser privadas, a menos que sejam absolutamente públicas (o que quase nunca é necessário, você deve usar propriedades / getters e setters).

As variáveis ​​fornecem amplamente o estado do objeto, e as variáveis ​​privadas impedem que outros entrem e alterem o estado do objeto.


5
Uma visão muito estreita do assunto. Há casos em que o acesso de campo pública se justifica, mesmo preferenciais
Roland Tepp

Certamente, é possível projetar objetos cujo estado não pode ser alterado (objetos imutáveis), mas essa não é uma regra geral aplicada a todas as classes. Na minha experiência, a maioria dos objetos facilita muito a alteração do estado do objeto.
David K

11
@DavidK Talvez o que o bbb quis dizer seja que "variáveis ​​privadas impedem que outras pessoas entrem e alterem indiscriminadamente o estado do objeto". Os métodos públicos podem alterar o estado privado do objeto, mas apenas de maneiras necessárias e consistentes para o funcionamento do objeto.
Max Nanasy

@ Max Nanasy: Sim, é possível controlar como o estado é alterado quando se oferece apenas métodos na interface pública. Por exemplo, pode haver um relacionamento entre os membros que deve ser satisfeito para que o objeto seja "auto-consistente" e você pode permitir que um estado auto-consistente seja alterado apenas para outro estado auto-consistente. Se todas essas variáveis ​​forem públicas, você não poderá aplicar isso. Mas também pode haver objetos em que você não deseja permitir nenhuma alteração; portanto, é importante deixar claro de quais dessas coisas estamos falando.
David K

2
  • O que as variáveis ​​privadas ajudam a impedir?

Trata-se de deixar claro quais propriedades e métodos são interface e quais são realmente as principais funcionalidades. Métodos / propriedades públicas são sobre outro código, geralmente o código de outro desenvolvedor usando seus objetos. Eu nunca trabalhei em equipes de mais de 100 no mesmo projeto, mas na minha experiência de talvez equipes de 3 a 5 com até 20 outros desenvolvedores usando coisas que eu escrevi, as outras preocupações parecem tolas.

Nota: Sou principalmente um desenvolvedor de JavaScript. Geralmente, não me preocupo com outros desenvolvedores que visualizam meu código e opero com plena consciência de que eles poderiam simplesmente redefinir minhas coisas a qualquer momento. Suponho que sejam competentes o suficiente para saber o que estão fazendo primeiro. Caso contrário, é improvável que eu estivesse trabalhando em uma equipe que não usa controle de origem.

  • Como você decide se um determinado conjunto de propriedades deve ser privado ou não? Se, por padrão, todos os campos DEVEM ser privados, por que existem membros de dados públicos em uma classe?

Eu costumava pensar que era bobagem colocar getters e setters em propriedades privadas quando você não estava realmente realizando nenhum tipo de validação ou outro tratamento especial da propriedade a ser configurada. Ainda não acho que seja sempre necessário, mas quando você está lidando com larga escala, alta complexidade, mas o mais importante é que muitos outros desenvolvedores confiam nos seus objetos se comportando de maneira consistente, pode ser útil fazer as coisas de uma maneira maneira consistente e uniforme. Quando as pessoas vêem métodos chamados getThatesetThat, eles sabem exatamente quais são as intenções e podem escrever seus objetos para interagir com os seus com a expectativa de que sempre consigam tomates em vez de tomahtos. Caso contrário, eles sabem que seu objeto está dando a eles algo que provavelmente não deveria, o que significa que está permitindo que outro objeto faça algo com esses dados que provavelmente não deveria. Você pode controlar isso conforme a necessidade.

A outra grande vantagem é que é mais fácil ter seus objetos entregando ou interpretando valores de maneira diferente de um getter ou setter com base em algum tipo de contexto de estado variável. Como eles acessam suas coisas com um método, é muito mais fácil alterar a maneira como seu objeto opera mais tarde, sem quebrar outro código que depende dele. O princípio importante é que apenas o seu objeto realmente altera os dados pelos quais você o responsabilizou. Isso é particularmente importante para manter seu código fracamente acoplado, o que é uma grande vitória em termos de portabilidade e facilidade de modificação.

  • Em que circunstâncias uma variável deve ser tornada pública?

Com funções de primeira classe (você pode passar funções como argumentos), não consigo pensar em muitas razões excelentes além de não ser extremamente necessário fazê-lo em projetos de menor escala. Sem ele, suponho que você possa ter membros que estão sendo processados ​​pesada e regularmente por outros objetos, na medida em que parece um pouco complicado chamar constantemente get e sets em um objeto que realmente não toca esses dados, mas que em em si me faria pensar por que o objeto era responsável por esses dados. De um modo geral, eu tenderia a reexaminar minha arquitetura quanto a falhas antes de decidir que uma propriedade de dados públicos é necessária. Na IMO, não há nada errado com um idioma que permita fazer algo que geralmente é uma má ideia. Alguns idiomas discordam.


IMHO, não há nada de particularmente errado em ter uma classe pública cujo único objetivo é expor variáveis ​​públicas. Na verdade, a JVM tem um número de classes internas para o efeito: int[], double[], Object[], etc. Deve-se, no entanto, ser muito cuidadosos sobre como se expõe casos de tal classe. O significado de void CopyLocationTo(Point p);[aceitar um Pointdo chamador] é mais claro que Point location(), uma vez que não está claro qual efeito Point pt = foo.location(); pt.x ++;terá no local de foo.
Super23

2

Veja este post meu para uma pergunta relacionada ao SO .

O escopo é que o escopo variável permite mostrar aos consumidores do seu código o que eles devem e não devem estar brincando. Uma variável privada pode conter dados que foram "controlados" usando um configurador de propriedades ou um método de processamento para garantir que o objeto inteiro esteja em estado consistente. Alterar o valor da variável privada diretamente pode fazer com que o objeto se torne inconsistente. Ao torná-lo privado, alguém precisa trabalhar muito e ter permissões de tempo de execução muito altas para alterá-lo.

O escopo adequado dos membros é, portanto, essencial no código de auto-documentação.


2

Vou falar sobre o valor do encapsulamento de uma perspectiva diferente, usando um exemplo real. Há muito tempo (início dos anos 80), um jogo foi escrito para o Radio Shack Color Computer chamado Dungeons of Daggorath. Alguns anos atrás, Richard Hunerlach o transportou de uma montadora de papel listando para C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ). Algum tempo depois, obtive o código e comecei a fatorá-lo novamente para fornecer um melhor encapsulamento ( http://dbp-consulting.com/stuff/ ).

O código já foi fatorado em objetos diferentes para lidar com agendamento, vídeo, entrada do usuário, criação de masmorras, monstros etc. mas você definitivamente pode dizer que foi portado pelo assembler. Minha maior tarefa era aumentar o encapsulamento. Com isso, pretendo obter diferentes partes do código para tirar o nariz dos negócios um do outro. Havia muitos lugares, por exemplo, que alteravam as variáveis ​​de vídeo diretamente para ter algum efeito. Alguns fizeram isso com verificação de erros, outros não, alguns tiveram idéias sutilmente diferentes sobre o que significava mudar isso. Houve muita duplicação de código. Em vez disso, a seção de vídeo precisava ter uma interface para realizar as tarefas desejadas, e o código para fazer isso pode estar em um só lugar, uma ideia, um lugar para depuração. Esse tipo de coisa era galopante.

Quando o código começou a ser separado, os bugs que ainda não haviam sido diagnosticados desapareceram. O código se tornou de maior qualidade. Cada tarefa passou a ser de responsabilidade de um lugar no código e havia apenas um lugar para acertar. (Ainda encontro mais sempre que faço outra passagem pelo código.)

Tudo o que é visível sobre o seu código é a sua interface. Quer você queira que seja ou não. Se você limitar a visibilidade o máximo possível, não será tentado a colocar o código no lugar errado mais tarde. Torna óbvio qual parte do código é responsável por quais dados. Ele cria um design melhor, mais limpo, mais simples e mais elegante.

Se você responsabiliza um objeto por seus próprios dados e fornece interfaces para todos os outros que precisam que algo aconteça, seu código fica MUITO mais simples. Apenas cai. Você tem pequenas rotinas simples que fazem apenas uma coisa. Menos complexidade == menos erros.


O difícil equilíbrio entre "a liberdade de nossos usuários da lib" e "menos problemas para nós". Estou começando a acreditar que o encapsulamento é melhor no sentido de evitar erros na minha própria codificação e ajudar os usuários finais a evitar erros também. Mas a falta de liberdade pode simplesmente afastá-los também, procurando alternativas ... Pode ser que a codificação ainda não seja usada, mas as funcionalidades previstas através de métodos públicos podem ajudar a equilibrar isso, mas exige mais tempo.
Poder de Aquário

Pena que a versão reformulado não está no github ....
jmoreno

2

Não tem nada a ver com confiança ou medo de ataques, é apenas sobre encapsulamento - não forçando informações desnecessárias sobre o usuário da classe.

Considere constantes privadas - elas não devem conter valores secretos (eles devem ser armazenados em outro lugar), não podem ser alterados, não precisam ser passados ​​para a sua classe (caso contrário, teriam que ser públicos). O único uso possível para eles é como constantes em OUTRAS classes. Mas se você fizer isso, essas classes agora dependem da sua classe, para realizar um trabalho não relacionado à sua classe. Se você alterar a constante, outras classes poderão quebrar. Isso é ruim para os dois lados - como escritor da sua turma, você quer a liberdade de mudar o máximo possível e não quer se preocupar com coisas fora do seu controle. Um consumidor da sua classe deseja poder depender dos detalhes expostos da sua classe, sem se preocupar com a alteração e a quebra do código.

Um consumidor da sua classe quer saber tudo o que é necessário para interagir com a sua classe e não quer saber nada sobre a sua classe que não mude a maneira como eles fazem isso: é uma trivialidade inútil. Se você usou um idioma com reflexão, com que frequência o aprendeu não como uma classe faz alguma coisa ou onde está lançando uma exceção inesperadamente, mas simplesmente o nome dos campos e métodos particulares? Eu estou apostando nunca. Porque você não tem utilidade para esse conhecimento.


1

O conceito OOP tem herança e tem um de seus recursos (Java ou C ++). Portanto, se vamos herdar (o que significa que vamos acessar as variáveis ​​da classe herdada), existe a possibilidade de afetar essas variáveis. Portanto, temos que decidir se as variáveis ​​podem ser alteradas ou não.

Apenas para esse fim, estamos usando modificadores de acesso no OOP. Um dos modificadores é privado, o que significa que ele pode ser acessado apenas por essa classe. Qualquer outra classe não pode afetar essas variáveis.

Como sabemos, protegido significa que ele pode ser acessado pela classe que vai herdar.

O motivo pelo qual existe um conceito modificador no OOP é devido a esses motivos (qualquer classe pode acessar outras variáveis ​​de classe usando o conceito OOP). Se não houver um conceito de modificador, significa que teria sido difícil herdar classes ou usar outros conceitos de OOP.


1

Conforme declarado por outros, variáveis ​​privadas são boas para evitar erros de uso que levam o objeto a um status inconsistente e difíceis de rastrear bugs e exceções imprevistas.

Mas, por outro lado, o que tem sido principalmente ignorado pelos outros é sobre campos protegidos.

Uma subclasse estendida terá acesso total aos campos protegidos, tornando o objeto tão frágil como se esses campos fossem públicos, mas essa fragilidade é limitada à própria classe de extensão (a menos que exponha ainda mais esses campos).

Portanto, os campos públicos são difíceis de serem considerados bons e, até a data, o único motivo para usá-los é nas classes usadas como parâmetro de configuração (uma classe muito simples, com muitos campos e nenhuma lógica, para que a classe seja passada apenas como um parâmetro para algum método).

Mas, por outro lado, os campos privados diminuem a flexibilidade do seu código para outros usuários.

Flexibilidade vs problemas, prós e contras:

Objetos instanciados pelo seu código na classe vanilla com campos protegidos são seguros e são de sua exclusiva responsabilidade.

Por outro lado, os objetos que estendem sua classe com campos protegidos, instanciados pelos usuários do seu código, são de responsabilidade deles, não sua.

Portanto, campos / métodos protegidos não bem documentados, ou se os usuários não entenderem realmente como esses campos e métodos devem ser usados, têm uma boa chance de causar problemas desnecessários a eles e a você.

Por outro lado, tornar a maioria das coisas privadas reduzirá a flexibilidade dos usuários e pode até afastá-los à procura de alternativas mantidas, pois eles podem não querer criar e manter uma bifurcação apenas para que as coisas aconteçam do seu jeito.

Portanto, um bom equilíbrio entre privado, protegido e público é o que realmente importa.

Agora, decidir entre privado e protegido é o verdadeiro problema.

Quando usar protegido?

Sempre que você entender que um campo pode ser altamente flexível, ele deve ser codificado como protegido. Essa flexibilidade é: de se tornar nulo (onde nulo é sempre verificado e reconhecido como um estado válido, sem gerar exceções), a ter restrições antes de ser usado por sua classe ex. > = 0, <100 etc, e corrigido automaticamente para valores acima / abaixo do fluxo, emitindo no máximo uma mensagem de aviso.

Portanto, para esse campo protegido, você pode criar um getter e usá-lo apenas (em vez de usar diretamente a variável de campo), enquanto outros usuários podem não usá-lo, caso desejem mais flexibilidade para seu código específico, no meu exemplo pode ser : se eles querem que valores negativos funcionem bem em sua classe estendida.


-1

imo @tdammers não está certo e é realmente enganador.

Existem variáveis ​​privadas para ocultar os detalhes da implementação. Sua turma Apode estar usando um arraypara armazenar pontuações. Amanhã você pode querer usar um treeou em priority queuevez disso. Todos os usuários de sua classe precisam de uma maneira de inserir pontuações e nomes addScore()e uma maneira de descobrir quem são os 10 melhores getTop(n).

Eles não precisam acessar a estrutura de dados subjacente. Parece bom? Bem, existem algumas ressalvas.

Você não deve armazenar muito estado de qualquer maneira, a maior parte não é necessária. O estado de armazenamento complicará seu código mesmo quando ele estiver "segregado" para uma classe específica. Pense bem, essa variável privada provavelmente mudou porque outro objeto chamou um método dessa classe. Você ainda precisa descobrir quando e onde esse método foi chamado e esse método público pode ser chamado em qualquer lugar, teoricamente.

A melhor coisa que você pode fazer é limitar a quantidade de estado que seu programa contém e usar funções puras sempre que possível.


-1
  • Acessar uma variável significa acessar seu valor quando o programa é executado, tornar uma variável privada protege seu valor quando o código é executado.
  • O objetivo da chamada "ocultação de dados" é manter os dados internos ocultos de outras classes que usam a classe. Essas outras classes só devem acessar o comportamento chamando métodos na classe, não alterando os valores das variáveis ​​diretamente.
  • Tornando a variável um membro de dados particulares, você pode garantir mais facilmente que o valor nunca seja modificado ou alterado. Por outro lado, se a variável for pública, outra classe poderá modificar ou alterar o valor que pode causar o travamento de outras partes do código.

11
isso não parece oferecer nada substancial sobre os pontos apresentados e explicados nas 17 respostas anteriores
gnat

-4

Você deve primeiro entender o conceito de programação orientada a objetos. Possui abstração, encapsulamento etc.

Abstração - Você obtém a idéia da lógica sem precisar saber detalhes sublinhados da implementação.

Encapsulamento - Você não pode ver a implementação sublinhada do objeto. Somente você pode ver a interface pública do objeto.

Agora em implementação específica com um programa orientado a objetos como C #, Java, C ++, você pode implementar esses conceitos.

private - A implementação que deve ser oculta do mundo exterior. Para que você possa mudar isso e o usuário da sua classe não seja afetado.

public - Esta é a interface pela qual se pode usar seu objeto.


11
protegido - acessível diretamente por subclasses (extensores) (java).
Poder de Aquário
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.