protegido
Vamos falar sobre questões de direitos de acesso protegidas. Veja o Exemplo 1 abaixo:
Test.java
classe myObject {} public class Test {public static void main (string [] args) {myObject obj = new MyObject (); obj.clone (); // Erro de compilação. }} O clone do método do objeto de tipo não é visível.
Já entendemos que objeto.clone () é um método protegido. Isso mostra que o método pode ser acessado por subclasses do mesmo pacote (java.lang) e ele (java.lang.object). Aqui está a classe MyObject (a herança padrão de java.lang.Object).
Da mesma forma, o teste também é uma subclasse de java.lang.Object. No entanto, o método protegido de outra subclasse não pode ser acessado em uma subclasse, embora as duas subclasses herdem da mesma classe pai.
Vejamos o Exemplo 2 novamente:
Test2.java
classe myObject2 {objeto protegido clone () lança CLONENOTSUPPPORTEDEXCECTIMENT {return super.clone (); }} classe pública test2 {public static void main (string [] args) lança clonenotsupportedException {myObject2 obj = new MyObject2 (); obj.clone (); // Compile OK. }} Aqui, substituímos o método clone () da classe pai na classe MyObject2, chamamos o método clone () em outra classe Test2 e compilar e passar.
A razão para a compilação é óbvia. Quando você substitui o método clone () na classe MyObject2, a classe MyObject2 e a classe Test2 estão no mesmo pacote; portanto, esse método protegido é visível para a classe Test2.
Nesse ponto, lembramos as declarações do capítulo 2.2 nos artigos de cópias rasos e profundos em Java, ② Subscrever o método clone () da classe base na classe derivada e a declarar como pública. Agora eu entendo o motivo dessa frase (para permitir que outras classes chamassem o método clone () desta classe, após a sobrecarga, o atributo do método clone () deve ser definido como público).
Vamos dar uma olhada no Exemplo 3:
Test3.Java
pacote 1class myObject3 {objeto protegido clone () lança clonenotsupportedException {return super.clone (); }} pacote 2Public Class Test3 estende MyObject3 {public static void main (string args []) {myObject3 obj = new MyObject3 (); obj.clone (); // Erro de compilação. Test3 tobj = new test3 (); tobj.clone (); // complie ok. }} Aqui eu uso a classe Test3 para herdar MyObject3. Observe que essas duas classes têm pacotes diferentes; caso contrário, é o caso do Exemplo 2. Na classe Test3, ligue para o método clone () da instância Tobj da classe Test3 e compile e passe. E também chamando o método clone () da instância obj da classe MyObject3 é chamado, e o erro de compilação!
Resultados inesperados, o método protegido não pode ser acessado por classes herdadas?
Deve ficar claro que a classe Test3 herde a classe MyObject3 (incluindo o método do clone), para que você possa chamar seu próprio método de clone no teste de classe 3. No entanto, o método protegido da classe MyObject3 é invisível para sua diferente subclasse BUN Test3.
Aqui está outra passagem de "Java em poucas palavras":
O acesso protegido requer um pouco mais de trabalho. Suponha que a Classe A declara um campo protegido X e seja estendido por uma classe B, que é definida em um pacote diferente (este último ponto é importante). A classe B herda o campo protegido X, e seu código pode acessar esse campo na instância atual de B ou em qualquer outra instância de B a que o código possa se referir. Isso não significa, no entanto, que o Código da Classe B possa começar a ler os campos protegidos de instâncias arbitrárias de A! Se um objeto é uma instância de A, mas não for uma instância de B, seus campos obviamente não são herdados por B, e o Código da Classe B não pode lê -los.
A propósito, muitos livros de Java na China são geralmente descritos dessa maneira ao introduzir permissões de acesso (várias formas e conteúdo consistente):
Controle de acesso do método:
estático
1. Palavra -chave estática (lembre -se disso primeiro e depois leia -o)
1) Métodos estáticos e variáveis estáticas são objetos que pertencem a uma determinada classe, mas não a uma classe.
2) Referências a métodos estáticos e variáveis estáticas são diretamente referenciadas através de nomes de classe.
3) Métodos não estáticos e variáveis não estáticas de membros não podem ser chamadas em métodos estáticos. Caso contrário, está tudo bem.
4) As variáveis estáticas são semelhantes às variáveis globais em outros idiomas em algum programa e podem ser acessadas fora da classe se não forem privadas.
2. Quando usar estático
Quando criamos uma instância de uma classe (objeto), geralmente usamos o novo método para que o espaço de dados dessa classe seja criado e seus métodos possam ser chamados.
No entanto, às vezes esperamos que, embora uma classe possa ser criada com n objetos (obviamente, o espaço de dados desses objetos N é diferente), alguns dos dados desses N objetos são os mesmos, ou seja, independentemente de quantas instâncias a classe possui, os dados têm uma cópia de memória dessas instâncias (ver Exemplo 1). É o caso das variáveis estáticas.
Outro cenário é que você deseja que um método não esteja associado a qualquer objeto da classe que o contém. Ou seja, esse método pode ser chamado mesmo que o objeto não seja criado. Um uso importante do método estático é chamá -lo sem criar nenhum objeto (consulte o Exemplo 2). Este é o caso de um método estático.
Há também um uso especial nas classes internas. Geralmente, uma classe normal não pode ser declarada estática, apenas uma classe interna pode fazê -lo. No momento, essa classe interna declarada como estática pode ser usada diretamente como uma classe normal sem a necessidade de instância de uma classe externa (consulte o Exemplo 3). Este é o caso das classes estáticas.
Exemplo 1
classe pública tstatic {static int i; public tstatic () {i = 4; } public tstatic (int j) {i = j; } public static void main (string args []) {System.out.println (tstatic.i); Tstatic t = novo tstatic (5); // Declare a referência do objeto e instancie -o. Neste momento i = 5 System.out.println (Ti); Tstatic tt = novo tstatic (); // Declare a referência do objeto e instancie -o. Neste momento i = 4 System.out.println (Ti); System.out.println (tt.i); System.out.println (Ti); }}
resultado:
05444
A variável estática é criada quando a classe é carregada. Enquanto a classe existir, a variável estática existe. Eles devem ser inicializados quando definidos. No exemplo acima, eu não é inicializado; portanto, o valor inicial padrão 0 será obtido. A variável estática só pode ser inicializada uma vez e a variável estática aceita apenas a última inicialização.
De fato, este ainda é um problema com várias instâncias compartilhando uma variável estática.
Exemplo 2
Não declarado como estático
classe Classa {int b; public void ex1 () {} classe classe {void ex2 () {int i; Classa A = new Classa (); i = ab; // aqui Acesso à variável do membro B A.Ex1 () através da referência do objeto; // aqui Acesso à função do membro ex1 através da referência do objeto}}}
Declarado como estático
classe Classa {static int b; estático void ex1 () {}} classe classeb {void ex2 () {int i; i = Classa.b; // aqui Acesso à variável de membro b Classa.ex1 () através do nome da classe; // aqui Acesso à função de membro ex1 através do nome da classe}} Ao usar métodos estáticos, tenha cuidado para que os métodos não estáticos não possam ser chamados em métodos estáticos e referência a variáveis não estáticas de membros (este ou super não podem ser referenciadas de forma alguma nos métodos estáticos). O motivo é muito simples. Para coisas estáticas, quando a JVM carrega a classe, ele abre esses espaços estáticos na memória (para que possa ser referenciado diretamente através do nome da classe) e, neste momento, a classe em que os métodos não estáticos e as variáveis de membro não estão localizados.
Portanto, se você deseja usar métodos não estáticos e variáveis de membro, poderá instanciar diretamente a classe em que a variável Método ou Membro está localizada no método estático. É assim que o vazio estático público faz isso.
Exemplo 3
public class Staticcls {public static void main (string [] args) {OuterCls.innerCls oi = new OutterCls.innerCls (); // Não há necessidade de novos externos antes deste}} class. }}}
resultado:
InnerCls
3. Inicialização estática
As variáveis definidas pela estática terão precedência sobre quaisquer outras variáveis não estáticas, independentemente da ordem em que aparecem. Um bloco de código estático (seguido por uma parte do código) é usado para executar a inicialização da variável estática explícita. Esse código será inicializado apenas uma vez e quando a classe for carregada pela primeira vez. Veja o exemplo abaixo.
classe Valor {static int c = 0; Value () {c = 15; } Value (int i) {c = i; } static void inc () {c ++; }} classe count {public static void prt (strings s) {System.out.println (s); } Valor v = novo valor (10); Valor estático v1, v2; estático {prt ("no bloco estático da contagem de cals v1.c =" + v1.c + "v2.c =" + v2.c); v1 = novo valor (27); prt ("no bloco estático da contagem de cals v1.c =" + v1.c + "v2.c =" + v2.c); v2 = novo valor (); prt ("no bloco estático da contagem de cals v1.c =" + v1.c + "v2.c =" + v2.c); }} classe pública tstaticBlock {public static void main (string [] args) {count ct = new count (); Count.prt ("no Main:"); Count.prt ("ct.c =" + ct.vc); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.v1.inc (); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.prt ("ct.c =" + ct.vc); }}
resultado:
No bloco estático da contagem de calss v1.c = 0 v2.c = 0 no bloco estático da contagem de calss v1.c = 27 v2.c = 27 no bloco estático da contagem de calss v1.c = 15 v2.c = 15 no principal: ct.c = 10v1.c = 10 v2.c = 10v1.c = 11 V2.C = 11s
Seja V, V1 ou V2, as variáveis de membro em que operam são a mesma variável estática c.
Na contagem da classe, V1 e V2 (valor estático v1, v2;), inicialize o bloco de código estático (estático {}) e finalmente inicialize v.