Oi! Vamos dedicar a lição de hoje ao encapsulamento e começar já com exemplos :) Princípios de encapsulamento - 1Aqui você tem uma máquina de refrigerante comum . Eu tenho uma pergunta para você: como isso funciona? Tente dar uma resposta detalhada: de onde vem o copo, como é mantida a temperatura interna, onde é armazenado o gelo, como a máquina sabe qual calda adicionar, etc.? Você provavelmente não tem respostas para essas perguntas. Justo, já que nem todo mundo usa essas máquinas. Eles não são tão populares hoje em dia. Vamos tentar dar outro exemplo. Algo que você definitivamente usa muitas vezes todos os dias. Ai vai uma ideia! Princípios de encapsulamento - 2Conte-nos como o mecanismo de pesquisa do Googlefunciona. Como exatamente ele procura informações relacionadas às palavras que você insere? Por que certos resultados são classificados como altos e outros não? Mesmo que você use o Google todos os dias, é provável que você não saiba. Mas isso não importa. Você não precisa saber disso. Você pode inserir consultas em um mecanismo de pesquisa sem pensar em como ele funciona. Você pode comprar refrigerante em uma máquina sem saber como ela funciona. Você pode dirigir um carro sem entender como funciona um motor de combustão interna e sem saber nada de física, mesmo no nível do ensino fundamental. Tudo isso é possível graças a um dos princípios fundamentais da programação orientada a objetos: o encapsulamento. Lendo vários artigos sobre programação orientada a objetos (OOP), você deve ter se deparado com o fato de que a programação envolve dois conceitos comuns: encapsulamento e ocultação . E os autores usam a palavra "encapsulamento" para significar uma coisa e depois outra. Exploraremos ambos os termos para que você obtenha um entendimento completo. Na programação, o significado original de encapsulamento é o agrupamento de dados, juntamente com os métodos que operam nesses dados, em uma única unidade (ou seja, uma "cápsula"). Em Java, a classe é a unidade de encapsulamento. Uma classe contém dados (campos) e métodos para trabalhar com esses dados.Princípios de encapsulamento - 3Isso pode parecer a abordagem obviamente correta para você, mas em outros paradigmas de programação, tudo é organizado de maneira diferente. Por exemplo, na programação funcional, os dados são estritamente separados das operações neles realizadas. No OOP, os programas consistem em cápsulas ou classes, que consistem em dados e funções para trabalhar com esses dados. Agora vamos falar sobre esconder . Como é que usamos todos os tipos de dispositivos complexos sem entender como eles são organizados ou como funcionam? É simples: seus criadores nos forneceram uma interface simples e conveniente. Em uma máquina de refrigerante, a interface são os botões do painel. Pressionando um botão, você escolhe o tamanho do copo. Apertando outro, você escolhe o sabor. Um terceiro é responsável por adicionar gelo. E isso é tudo que você precisa fazer. A organização interna da máquina não importa. O que importa é que ele foi projetado de forma que exige que o usuário aperte três botões para obter o refrigerante . O mesmo é verdade sobre os carros. Não importa o que está acontecendo lá dentro. O que importa é que quando você pressiona o pedal direito, o carro avança, e quando você pressiona o pedal esquerdo, ele desacelera.. Isso é o que significa esconder. Todos os "interiores" de um programa estão ocultos do usuário. Para o usuário, essas informações supérfluas e desnecessárias. O usuário precisa do resultado final, não do processo interno. Vejamos a Autoclasse como exemplo:
public class Auto {

   public void go() {

       /* Some complicated things happen inside the car.
       As a result, it moves forward */
   }

   public void brake() {

       /* Some complicated things happen inside the car.
       As a result, it slows down. */
   }

   public static void main(String[] args) {

       Auto auto = new Auto();

       // From the user's perspective,

       // one pedal is pressed and the car accelerates.
       auto.gas();

       // The other is pressed, and the car slows down.
       auto.brake();
   }
}
Aqui está a aparência da ocultação de implementação em um programa Java. É como na vida real: o usuário recebe uma interface (métodos). Se o usuário precisar de um carro em um programa para executar uma ação, basta chamar o método desejado. O que acontece dentro desses métodos é supérfluo. O que importa é que tudo funcione como deveria. Aqui estamos falando sobre ocultação de implementação . Além disso, o Java também possui ocultação de dados . Escrevemos sobre isso na lição sobre getters e setters , mas revisar o conceito não vai doer. Por exemplo, temos uma Catclasse:
public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }


}
Talvez você se lembre do problema com esta classe da última lição? Se não, vamos lembrar agora. O problema é que seus dados (campos) estão abertos a todos — outro programador pode facilmente criar um gato sem nome com peso 0 e idade de -1000 anos:
public static void main(String[] args) {

   Cat cat = new Cat();
   cat.name = "";
   cat.age = -1000;
   cat.weight = 0;

}
Talvez você possa ficar de olho se um de seus colegas de trabalho criou objetos com estado inválido, mas seria muito melhor excluir até mesmo a possibilidade de criar tais "objetos inválidos". Princípios de encapsulamento - 4Os seguintes mecanismos nos ajudam a ocultar dados:
  1. modificadores de acesso ( privado , protegido , padrão do pacote )
  2. getters e setters
Por exemplo, podemos marcar lá para ver se alguém está tentando atribuir um número negativo à idade do gato. Como dissemos anteriormente, os autores de vários artigos sobre encapsulamento às vezes significam combinar dados e métodos, ou ocultá-los, ou ambos (combiná-los e ocultá-los). Java tem ambos os mecanismos (isso não é necessariamente verdade para outras linguagens OOP), então o último significado é o mais correto. O encapsulamento nos dá várias vantagens importantes:
  1. Controle sobre o estado correto de um objeto. Houve exemplos disso acima. Um setter e o modificador private garantem que nosso programa não terá gatos com peso 0.

  2. Facilidade de uso através de uma interface. Apenas os métodos são deixados "expostos" ao mundo exterior. Chamar métodos é suficiente para obter um resultado — não há absolutamente nenhuma necessidade de se aprofundar nos detalhes de como eles funcionam.

  3. As alterações de código não afetam os usuários. Fazemos toda e qualquer alteração dentro dos métodos. Isso não afeta o usuário do método: se o código correto anteriormente era "auto.gas()" para aplicar o pedal do acelerador, então continuará sendo. O fato de termos alterado algo dentro do método gas() permanece invisível para o usuário: como antes, o chamador simplesmente recebe o resultado desejado.