Pilares de POO em Java
Abstração
A abstração na POO é a capacidade de ocultar detalhes irrelevantes ou complexos de um problema e focar nos aspectos essenciais. Ela é implementada por meio de classes, que são modelos que descrevem os atributos e comportamentos comuns de um grupo de objetos. Por exemplo, a classe Animal pode ter os atributos nome, espécie e idade, e os métodos comer e dormir.
Podemos destacar três principais pontos da abstração na POO:
- Identidade: Cada objeto deve ter uma identidade única dentro do sistema para que não haja conflito.
- Propriedades: Os objetos podem ter propriedades que os definem.
- Métodos: Os objetos podem ter métodos que representam as ações que eles podem realizar.
A abstração traz vários benefícios para o desenvolvimento de software, como:
- Facilitar a compreensão do código, pois permite que os desenvolvedores vejam o problema de forma mais simples e clara.
- Melhorar a reusabilidade do código, pois permite que os desenvolvedores criem código modular e reutilizável. Por exemplo, uma classe Gato pode herdar da classe Animal.
- Evitar erros, pois permite que os desenvolvedores escondam detalhes de implementação que podem causar problemas. Por exemplo, uma classe Aplicativo pode ter uma classe interna Conexão que representa uma conexão com um banco de dados.
Em Java temos as classes abstratas não podem ser instanciadas diretamente. Elas só podem ser implementadas por outras classes. Você pode pensar da seguinte maneira, uma classe abstrata te diz o que fazer, mas não te diz como fazer. E com isso espero que possa diferenciar o pilar da abstração das classes abstratas no Java.
Encapsulamento
O encapsulamento na POO é a técnica de esconder as propriedades de um objeto, criando uma caixa preta que protege os dados internos. Ele é implementado por meio de propriedades privadas, que só podem ser acessadas ou modificadas por meio de métodos especiais chamados getters e setters. Essa técnica evita o acesso direto às propriedades do objeto, aumentando a segurança da aplicação.
O encapsulamento pode ser comparado com o que acontece no mundo real. Por exemplo, quando ligamos a televisão, não precisamos saber como ela funciona internamente. Podemos dizer que os métodos que ligam a televisão estão encapsulados.
Em Java, o encapsulamento é implementado através de modificadores de acesso. Os modificadores de acesso permitem controlar quem pode acessar os dados e funções de um objeto.
Os modificadores de acesso mais comuns são:
public
: os dados e funções que possuem o modificadorpublic
podem ser acessados por qualquer objeto.protected
: os dados e funções que possuem o modificadorprotected
podem ser acessados por classes que são subclasses da classe que os define.private
: os dados e funções que possuem o modificadorprivate
só podem ser acessados pela classe que os define.
Herança
A herança é um conceito da programação orientada a objetos que permite criar novas classes a partir de outras já existentes, aproveitando seus atributos e métodos. A herança facilita o reuso de código, a organização e a manutenção do software.
Em Java, a herança é implementada por meio da palavra-chave extends, que indica qual classe é a superclasse (ou classe base) e qual classe é a subclasse (ou classe derivada). A subclasse herda todos os membros da superclasse, podendo adicionar novos atributos e métodos ou sobrescrever os existentes.
Um exemplo de herança em Java é a classe Object, que é a superclasse de todas as outras classes. Ela fornece alguns métodos comuns, como toString, equals e hashCode, que podem ser usados ou redefinidos pelas subclasses.
Outro exemplo é a classe Pessoa, que pode ter os atributos nome e matrícula, e ser a superclasse de outras classes, como Aluno, Professor e Funcionário. Essas subclasses podem herdar os atributos de Pessoa e adicionar outros específicos, como curso, salário e cargo.
Polimorfismo
O polimorfismo é a capacidade de um objeto ser tratado como um objeto de outro tipo. Isso permite que os objetos sejam utilizados de forma mais flexível e genérica. Mas o que isso quer dizer?
Você já viu um camaleão? Ele é um bicho que consegue mudar de cor conforme o ambiente. Ele faz isso para se adaptar e se proteger dos predadores. O polimorfismo na POO é parecido com isso. Ele é a capacidade de um objeto mudar de comportamento conforme a situação. Como assim? Bom, vamos ver um exemplo.
Imagine que você tem um objeto chamado Eletrodoméstico. Esse objeto tem uma ação, ou método, chamado Ligar(). Agora, imagine que você tem dois objetos que são filhos do Eletrodoméstico: Televisão e Geladeira. Você acha que eles vão ligar do mesmo jeito? Claro que não! A televisão precisa de um controle remoto, e a geladeira precisa de uma tomada. Então, você precisa reescrever o método Ligar() para cada um deles.
Isso é o polimorfismo: a possibilidade de um objeto ter vários comportamentos diferentes para o mesmo método. Isso é muito útil para aproveitar o código que já existe e fazer ele funcionar de acordo com a necessidade.
Mas cuidado: o polimorfismo não é igual em todas as linguagens de programação. Algumas linguagens têm um jeito especial de fazer o polimorfismo, usando palavras-chave ou símbolos específicos. Por exemplo, em C#, você precisa usar as palavras virtual e override para indicar que um método pode ser reescrito nas classes filhas. Em Java, o polimorfismo é implementado através da sobrecarga de métodos e da herança, você só precisa usar o símbolo @Override.
A sobrecarga de métodos permite que uma classe tenha métodos com o mesmo nome, mas com parâmetros diferentes. Isso permite que os métodos sejam chamados de forma mais flexível, de acordo com os parâmetros que são passados. A herança também permite o polimorfismo, pois permite que objetos de diferentes classes sejam tratados de forma semelhante.