Estive pesquisando e conheço a diferença teórica.
- public - Qualquer classe / função pode acessar o método / propriedade.
- protected - Somente esta classe e quaisquer subclasses podem acessar o método / propriedade.
- privado - Somente esta classe pode acessar o método / propriedade. Nem será herdado.
Está tudo bem e bem, a questão é: qual é a diferença prática entre eles? Quando você usaria private
e quando você usaria protected
? Existe uma boa prática padrão ou aceitável sobre esta?
Até agora, para manter o conceito de herança e polimorfismo, eu uso public
para qualquer coisa que deva ser acessada de fora (como construtores e funcionalidade de classe principal) e protected
para métodos internos (lógica, métodos auxiliares etc.). Estou no caminho certo?
(Observe que esta pergunta é para mim, mas também para referência futura, pois ainda não vi uma pergunta como essa).
oop
language-agnostic
coding-style
Fantasma de Madara
fonte
fonte
internal
na linguagem C # que restringe o nível de acesso de uma classe ou de seus membros em um assembly físico. No entanto, não tenho certeza sobre o suporte ou algo semelhante em outros idiomas.Respostas:
Não, você não está no caminho certo. Uma boa regra geral é: torne tudo o mais privado possível. Isso torna sua classe mais encapsulada e permite alterar os elementos internos da classe sem afetar o código usando sua classe.
Se você projetar sua classe para ser herdável, escolha cuidadosamente o que pode ser substituído e acessível pelas subclasses e torne-o protegido (e final, falando sobre Java, se você deseja torná-lo acessível, mas não substituível). Mas lembre-se de que, assim que você aceitar ter subclasses da sua classe e houver um campo ou método protegido, esse campo ou método fará parte da API pública da classe e não poderá ser alterado posteriormente sem quebrar as subclasses.
Uma classe que não deve ser herdada deve ser finalizada (em Java). Você pode relaxar algumas regras de acesso (privadas para protegidas, finais para não finais) para testar a unidade, mas depois documentá-las e deixar claro que, embora o método esteja protegido, não deve ser substituído.
fonte
private
vs.protected
Quando quero que uma propriedade seja herdada e quando não quero? Eu realmente não posso dizer se um usuário, por vezes, no futuro quer levar minha classe e estendê-lo ...Permita-me começar dizendo que estou falando principalmente sobre o acesso ao método aqui e, em menor grau, marcando as classes como finais, e não como membro.
A velha sabedoria
fazia sentido nos dias em que foi escrito, antes que o código aberto dominasse o espaço da biblioteca do desenvolvedor e o VCS / mgmt de dependência. tornou-se hiper colaborativo graças ao Github, Maven, etc. Naquela época, também havia dinheiro a ser ganho, restringindo a (s) maneira (s) em que uma biblioteca poderia ser utilizada. Passei provavelmente os primeiros 8 ou 9 anos da minha carreira aderindo estritamente a essa "melhor prática".
Hoje, acredito que seja um mau conselho. Às vezes, existe um argumento razoável para marcar um método como privado ou como final de aula, mas é extremamente raro e, mesmo assim, provavelmente não está melhorando nada.
Você já:
Estas são as três maiores racionalizações que ouvi sobre como marcar métodos privados por padrão:
Racionalização nº 1: não é seguro e não há motivo para substituir um método específico
Não posso contar o número de vezes que me enganei sobre a necessidade ou não de substituir um método específico que escrevi. Tendo trabalhado em várias bibliotecas populares de código aberto, aprendi da maneira mais difícil o verdadeiro custo de marcar as coisas como privadas. Geralmente, elimina a única solução prática para problemas imprevistos ou casos de uso. Por outro lado, nunca em mais de 16 anos de desenvolvimento profissional me arrependi de marcar um método protegido em vez de privado por motivos relacionados à segurança da API. Quando um desenvolvedor decide estender uma classe e substituir um método, conscientemente está dizendo "eu sei o que estou fazendo". e por uma questão de produtividade que deve ser suficiente. período. Se for perigoso, observe nos Javadocs de classe / método, não basta fechar a porta às cegas.
Os métodos de marcação protegidos por padrão são uma atenuação para um dos principais problemas no desenvolvimento moderno de SW: falta de imaginação.
Racionalização # 2: mantém a API / Javadocs públicos limpos
Essa é mais razoável e, dependendo do público-alvo, pode até ser a coisa certa a se fazer, mas vale a pena considerar qual é o custo de manter a API "limpa": extensibilidade. Pelas razões mencionadas acima, provavelmente faz mais sentido marcar itens protegidos por padrão por precaução.
Racionalização nº 3: meu software é comercial e preciso restringir seu uso.
Isso também é razoável, mas como consumidor, eu iria sempre com o concorrente menos restritivo (assumindo que não existem diferenças significativas de qualidade).
Nunca diga nunca
Não estou dizendo que nunca marque métodos como particulares. Estou dizendo que a melhor regra é "tornar os métodos protegidos, a menos que haja uma boa razão para não fazê-lo".
Este conselho é mais adequado para quem trabalha em bibliotecas ou projetos de maior escala que foram divididos em módulos. Para projetos menores ou mais monolíticos, isso não costuma importar muito, já que você controla todo o código e é fácil alterar o nível de acesso do seu código, se / quando você precisar. Mesmo assim, eu ainda daria o mesmo conselho :-)
fonte
Rationalization # 1
- Quando eu marca de algo tão protegido que eu escolher para fazer isso explicitamente como eu sinto que este comportamento não é definitiva e pode ser um caso onde os meus filhos aulas gostaria de substituí-lo. Se não tenho tanta certeza, gostaria de torná-lo privado por padrão. Especialmente em um idioma como C #, que mantém um método não virtual por padrão, adicionar apenas um especificador de acesso protegido não faz sentido. Você precisa adicionar palavras-chavevirtual
e ambosprotected
para deixar sua intenção muito clara. Além disso, as pessoas preferem associação sobre a herança assimprotected
como padrão é difícil de perceberPare de abusar de campos particulares !!!
Os comentários aqui parecem ser extremamente favoráveis ao uso de campos particulares. Bem, então eu tenho algo diferente a dizer.
Os campos privados são bons em princípio? Sim. Mas dizer que uma regra de ouro é tornar tudo privado quando você não tem certeza se está definitivamente errado ! Você não verá o problema até encontrar um. Na minha opinião, você deve marcar os campos como protegidos se não tiver certeza .
Há dois casos em que você deseja estender uma classe:
Não há nada de errado com campos particulares no primeiro caso. O fato de as pessoas estarem abusando de campos particulares o torna tão frustrante quando você descobre que não pode modificar nada.
Considere uma biblioteca simples que modela carros:
O autor da biblioteca pensou: não há razão para que os usuários da minha biblioteca precisem acessar os detalhes da implementação,
assembleCar()
certo? Vamos marcar o parafuso como privado.Bem, o autor está errado. Se você deseja modificar apenas o
assembleCar()
método sem copiar toda a classe no seu pacote, você está sem sorte. Você precisa reescrever seu próprioscrew
campo. Digamos que este carro use uma dúzia de parafusos, e cada um deles envolva algum código de inicialização simples em diferentes métodos particulares, e esses parafusos são todos marcados como particulares. Neste ponto, ele começa a chupar.Sim, você pode argumentar comigo que bem, o autor da biblioteca poderia ter escrito um código melhor, então não há nada errado com os campos privados . Não estou argumentando que o campo privado é um problema com OOP . É um problema quando as pessoas os estão usando.
A moral da história é que, se você está escrevendo uma biblioteca, nunca sabe se seus usuários desejam acessar um campo específico. Se não tiver certeza, marque-o
protected
para que todos fiquem mais felizes mais tarde. Pelo menos não abuse do campo privado .Eu apoio muito a resposta de Nick.
fonte
Li um artigo há um tempo atrás, que falava em bloquear todas as aulas o máximo possível. Torne tudo final e privado, a menos que você precise expor imediatamente alguns dados ou funcionalidades ao mundo exterior. É sempre fácil expandir o escopo para ser mais permitido posteriormente, mas não o contrário. Primeiro, considere fazer o maior número possível de coisas, o
final
que tornará a escolha entreprivate
eprotected
muito mais fácil.Agora, se você tiver uma aula final, torne tudo privado, a menos que algo seja absolutamente necessário ao mundo - torne isso público.
Se você tiver uma classe que possui subclasse (s), examine cuidadosamente todas as propriedades e métodos. Primeiro considere se você deseja expor essa propriedade / método a subclasses. Se você o fizer, considere se uma subclasse pode causar estragos no seu objeto se isso prejudicou o valor da propriedade ou a implementação do método no processo de substituição. Se possível, e você deseja proteger a propriedade / método da sua classe, mesmo das subclasses (parece irônico, eu sei), então torne-a privada. Caso contrário, torne-o protegido.
Disclaimer: Eu não programa muito em Java :)
fonte
final class
em Java é uma classe da qual não pode ser herdada. Afinal method
não é virtual, ou seja, não pode ser substituído por uma subclasse (os métodos Java são virtuais por padrão). Afinal field/parameter/variable
é uma referência variável imutável (no sentido de que não pode ser modificado após ter sido inicializado).Quando você usaria
private
e quando você usariaprotected
?A herança privada pode ser implementada em termos de relacionamento, e não em um relacionamento IS-A . Simplificando, a interface externa da classe herdada não possui relação (visível) com a classe herdada. Ela usa a
private
herança apenas para implementar uma funcionalidade semelhante que a classe Base fornece.Ao contrário de Herança Privada, a herança Protegida é uma forma restrita de Herança, em que a classe derivada é do tipo IS-A da classe Base e deseja restringir o acesso dos membros derivados apenas à classe derivada.
fonte
Bem, é tudo uma questão de encapsulamento, se as classes de folha de pagamento lidam com cobrança de pagamento e, em seguida, na classe de produto, por que ela precisaria de todo o processo de cobrança? nada além desse público para aqueles em que outras classes usariam também, protegido para aqueles limites apenas para a extensão de classes. Como você é madara uchiha, o privado é como
"limboo"
você pode vê-lo (você classifica apenas uma classe).fonte