Encapsulamento é a forma como classes, métodos e atributos podem ser
vistos ou utilizados por outras classes. Este importante conceito
também é conhecido dentro do mundo da orientação por objetos como
acessibilidade ou 
data hiding (ocultação de dados). Os especificadores
de acesso são responsáveis por definir o grau de encapsulamento exibido
por uma classes e seus elementos.
Utilizando desta técnica podemos ter um controle maior a partes de nossas
classes. Podemos, por exemplo, restringir o usuário que instância a classe,
que passa apenas a conhecer o que é necessário para o uso dos objetos 
criados. Podemos ainda fazer com que certos atributos assumam valores
restritos, mantendo-se a consistência e a integridade dos dados armazenados
na classe.
Para que essas características citadas possam ser elaboradas fazemos uso
dos especificadores de acesso que ocultam partes da classe. Utilizamos
alguns deles rapidamente no 
artigo 3. 
As palavras reservadas aos especificadores de acesso são 
public, 
private, 
package e 
protected.
No 
artigo 4 utilizamos na classe 
Arcondicionado um atributo chamado "opcao", onde o especificador de acesso protected 
estava relacionado a ele no código. Agora utilizaremos o especificador 
private, 
impedindo que valores inconsistentes sejam armazenados nele, seu uso só pode ser 
indiretamente realizado por meio de métodos públicos pertencentes a classe. Sendo assim, 
garantimos a consistência desse atributo.
 
// Arcondicionado.java
public class Arcondicionado {
  // atributos, agora com private
  private int opcao;
  // métodos/
  public void trocarTemp(int op) {
    // verifica se a opção informada é valida
    if(op >= 0 && op <= 3) {
      opcao = op;
    }
  }
  
  public int obterTemp() {
    return opcao;
  }
}
Podemos testar esta condição instanciando um objeto Arcondicionado tentando
atribuir um valor diretamente no atributo "opcao".
// ErroDeAcesso.java
public class ErroDeAcesso {
  public static void main (String args[]) {
    Arcondicionado arno = new Arcondicionado();
    System.out.println(arno.opcao);
    arno.opcao = 2;
    System.out.println(arno.opcao);
  }
}
Ao compilar o código fiquem atentos às mensagens de erros, pois elas evidenciam a restrição.
Agora podemos observar que a restrição a certas partes da classe representa uma forma 
de divisão de código, pois separa a interface do usuário da classe, atributos e métodos 
públicos de uma classe, da interface do programador da classe. Atributos e métodos protegidos 
que formam a interface do programador da classe só podem ser acessados por novas classes que 
sejam criadas por meio do mecanismo de 
herança. Elementos declarados como privados 
(private), são exclusivos da classe.
A utilização correta destas interfaces permitem:
-  Um código mais claro, pois ficam evidentes os membros que permitem
funcionalidades reais daqueles que são auxiliares.
 -  Os erros de programação diminuem pois as interfaces tornam-se mais
simples.
 -  São proporcionadas facilidades para extensão, criando classes novas
através de classes existentes.
 -  A facilidade de modificação aumenta, porque a classe é conhecida pela
sua interface, logo modificações que não afetem a interface são transparentes 
para usuários da classe.
 
Uma observação importante, quando um especificador de acesso não é determinado 
o Java assume o tipo "package", que é semelhante ao 
public para acesso 
de classes que pertencem ao mesmo pacote, protegido para subclasses e privado 
para instâncias das subclasses.
Os especificadores de acesso "private" e "protected" podem ser equivalentes com 
os especificadores "package" e "public", porem isso só ocorre quando tratamos a 
classe e suas instâncias. Assim quando utilizamos subclasses e suas instâncias 
esses especificadores tem características bastantes distintas. Essa idéia ficará 
mais clara quando trabalharmos com 
herança.
Podemos resumir dizendo que a técnica de encapsulamento é capaz de separar o projeto 
(design) da implementação (coding).