A seguir, é pseudo-código, tentei em Java e PHP e ambos funcionaram:
class Test {
private int a = 5;
public static function do_test(){
var t = new Test();
t.a = 1;
print t.a // 1
}
}
Test::do_test();
Por que você pode fazer isso no paradigma OOP e para que serve?
equals
que é necessário verificar os campos particulares de outra instância. (Posting como comentário, como este é curto, e nada sobre a OOP-ness desta abordagem)this
, portanto, os únicos objetos de sua própria classe em que eles podem chegar são os que eles mesmos criam (ou são passados como parâmetro). Portanto, se você considera isso uma violação do encapsulamento ou uma falha de segurança, não é muito grande e pode não valer a pena ser corrigida.Respostas:
Em Java, variáveis privadas são visíveis para toda a classe. Eles podem ser acessados a partir de métodos estáticos e de outras instâncias da mesma classe.
Isso é, por exemplo, útil em métodos de fábrica . Um método de fábrica geralmente inicializa um objeto que é tão complexo que você não deseja deixá-lo no código do aplicativo. Para fazer a inicialização, o método factory geralmente precisa acessar os internos da classe que você não deseja expor. Ser capaz de acessar diretamente as variáveis privadas facilita sua vida.
No entanto, quando você deseja ocultar os detalhes de implementação de uma classe, mesmo de métodos estáticos ou de outras instâncias dessa classe, pode seguir o padrão de dados da classe privada . Coloque todas as variáveis privadas de uma classe em uma classe interna privada e delegue quaisquer getters ou setters a getters e setters dessa classe interna.
Outra opção é definir uma interface para a classe que declare todos os métodos públicos da classe e, em seguida, referencie a classe sob essa interface sempre que possível. Uma referência ao tipo de interface não pode ser usada para acessar diretamente qualquer coisa não declarada na interface, não importa onde (exceto com reflexão, é claro). Quando você usa uma linguagem de programação orientada a objetos que não possui interfaces (como C ++, por exemplo), elas podem ser simuladas com uma classe base abstrata que é herdada pela classe real.
fonte
Algumas linguagens e estruturas de tempo de execução (por exemplo, Java, .NET) pressupõem que qualquer pessoa que esteja compilando o código para uma classe específica possa confiar em não usar nenhum membro privado de qualquer instância dessa classe de maneiras que possam prejudicar sua correta Operação. Outras linguagens e estruturas são mais restritivas a esse respeito e não permitem o acesso a membros particulares de uma instância, exceto pelo código em execução nessa instância . Ambos os projetos têm vantagens e desvantagens.
A maior vantagem de permitir que qualquer código dentro de uma classe acesse membros particulares de qualquer instância é que há casos em que esse nível de acesso é apropriado e o
private
trabalho dessa maneira elimina a necessidade de ter um qualificador de acesso diferente disponível para esse fim ou caso contrário, force o código a expor os membros mais amplamente do que seria ideal.Uma vantagem de proibir esse acesso (como no COM) (Microsoft Common Object Model) é que ele permite que o código externo trate as classes como interfaces. Se uma classe
ImmutableMatrix
contiver umdouble[][]
campo de apoio privado ou protegido , e se o código dentro da classe examinar a matriz de apoio de outras instâncias, não será possível definir uma classe não suportada por matriz (por exemploZeroMatrix
,IdentityMatrix
) que o código externo possa usar como umImmutable2dMatrix
, sem que a classe tendo incluindo o campo de suporte. Se nada dentroImmutable2dMatrix
usar membros privados de qualquer instância quethis
não seja, seria possível renomear a classe paraImmutableArrayBackedMatrix
e definir uma novaImmutableMatrix
classe abstrata que poderia terImmutableArrayBackedMatrix
, como subtipos, as classes acima mencionadas sem o array.Observe que essa refatoração não seria impedida se o idioma "permitisse"
ImmutableMatrix
examinar a matriz de apoio para outras instânciasthis
, a menos que o idioma aproveitasse essa capacidade e realmente examinasse instâncias externas. O principal efeito de um idioma restringir esse uso é que ele fará o compilador gritar imediatamente em qualquer tentativa de escrever código que não seja passível de refatoração.fonte
Java não é estritamente uma linguagem orientada a objetos, mas uma linguagem baseada em classe - a classe determina as operações e o acesso ao comportamento, e não a instância.
Portanto, não se surpreenda demais porque isso permite que você faça coisas que não são estritamente orientadas a objetos.
Como o método está no mesmo escopo de classe da instância, ele tem acesso total a membros privados. Regras semelhantes governam instâncias de classes internas que acessam dados de instâncias de classes externas - uma instância de uma classe interna pode acessar membros privados da classe externa.
Isso é herdado do C ++, onde é útil para criar construtores de copiar e mover. Também é útil para comparar ou combinar dois objetos em que seu valor depende de membros que não são acessíveis publicamente de maneira eficiente (por exemplo, o getter para uma matriz em Java deve copiar a matriz para que o código do cliente não possa modificá-lo, alterando o estado interno do objeto, mas ter que copiar matrizes para comparar a igualdade do objeto não é eficiente)
fonte