Programação Orientada a Objetos: Conceitos Essenciais
A Programação Orientada a Objetos (POO) é um paradigma que organiza o software em objetos que interagem entre si. Cada objeto é uma instância de uma classe e pode conter atributos (dados) e métodos (ações). A seguir, vamos explorar os conceitos essenciais dessa abordagem.
Classe
Uma classe é o molde para criar objetos. Ela define os atributos e os métodos que os objetos criados a partir dela terão.
Record
O record cria uma classe imutável de forma simplificada, onde os valores são passados por parâmetro e não é possível adicionar atributos ou métodos adicionais.
record Ponto(int x, int y) {}
Herança
A herança permite que uma classe herde atributos e métodos de outra, facilitando o reaproveitamento de código e a criação de hierarquias entre as classes.
class Animal {
void fazerSom() {
System.out.println("Som do animal");
}
}
class Cachorro extends Animal {
@Override
void fazerSom() {
System.out.println("Latido!");
}
}
Polimorfismo
O polimorfismo permite que o mesmo método tenha diferentes comportamentos, dependendo da classe que o implementa. Isso é possível quando uma subclasse redefine um método da superclasse.
class Animal {
void fazerSom() {
System.out.println("Som do animal");
}
}
class Gato extends Animal {
@Override
void fazerSom() {
System.out.println("Miau!");
}
}
public class Teste {
public static void main(String[] args) {
Animal meuAnimal = new Gato();
meuAnimal.fazerSom(); // Saída: Miau!
}
}
Abstract
Uma classe ou método abstract não pode ser instanciado diretamente e serve como modelo para outras classes. As classes filhas devem implementar os métodos abstratos.
abstract class Veiculo {
abstract void acelerar();
}
class Carro extends Veiculo {
void acelerar() {
System.out.println("Carro acelerando!");
}
}
sealed e non-sealed
sealed
: Usado para restringir quais classes podem herdar de uma classe de uma classe selada. Uma classe selada permite que você defina explicitamente quais subclasses são permitidas, aumentando a segurança do design.non-sealed:
Usado em uma classe que herda de uma classe sealed, permitindo que essa classe seja posteriormente estendida por outras classes. Ou seja, "quebra" a limitação imposta pelo sealed.
sealed class Forma permits Circulo, Quadrado {}
non-sealed class Circulo extends Forma {} // Pode ser herdada livremente
final class Quadrado extends Forma {} // Não pode ser herdada
Final
É usado para declarar constantes, métodos que não podem ser sobrescritos e classes que não podem ser herdadas. Ou seja:
Classe final
: Não pode ser herdada.
Método final
: Não pode ser sobrescrito.
Variável final
: Não pode ser alterada
public class Main {
public static final int MAX_VALUE = 100; // A constante MAX_VALUE não pode ser alterada
public static void main(String[] args) {
System.out.println("O valor máximo é: " + MAX_VALUE);
}
}
Interface
Uma interface define um conjunto de métodos que as classes devem implementar. Ela permite múltipla implementação, ou seja, uma classe pode implementar várias interfaces.
interface Volante {
void virar();
}
class Carro implements Volante {
public void virar() {
System.out.println("Virando o carro");
}
}
Interface Funcional
Uma interface funcional possui apenas um método abstrato. Ela pode ter métodos default ou static.
var consumer = new Consumer<User>() {
@Override
public void accept(User user) {
System.out.println(user);
}
};
users.forEach(consumer);
que pode ser reduzido de duas formas usando lambda*:
users.forEach((User user) -> { System.out.println(user); });
ou
users.forEach(System.out::println);
*Lambda
É uma expressão que permite passar comportamento como parâmetro para métodos ou criar funções de forma concisa. É uma maneira de escrever código funcional sem a necessidade de usar classes anônimas. As lambdas têm a seguinte estrutura:
(parâmetros) -> expressão ou bloco de código
Exemplo:
public class Main {
public static void main(String[] args) {
// Lambda para somar dois números
BiFunction<Integer, Integer, Integer> soma = (a, b) -> a + b;
System.out.println(soma.apply(3, 4)); // Imprime 7
}
}