Blog Logo

15 Oct 2023 ~ 22 min read

JAVA - Mini Curso


Seja bem-vindo ao mundo fascinante da programação em Java! Este curso é uma jornada emocionante para aqueles que desejam explorar uma das linguagens mais versáteis e amplamente utilizadas no desenvolvimento de software.

Tipos de Dados

Em Java, existem diferentes tipos de dados que você pode usar para armazenar valores.

Tipos Primitivos:

  1. Inteiros:

    • byte: 8 bits, armazena números inteiros de -128 a 127.
    • short: 16 bits, armazena números inteiros de -32,768 a 32,767.
    • int: 32 bits, armazena números inteiros de -2,147,483,648 a 2,147,483,647.
    • long: 64 bits, armazena números inteiros de -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807.
  2. Ponto flutuante:

    • float: 32 bits, armazena números de ponto flutuante de precisão simples.
    • double: 64 bits, armazena números de ponto flutuante de precisão dupla (recomendado para uso geral).
  3. Booleano:

    • boolean: armazena valores verdadeiro ou falso (true ou false).
  4. Caracteres:

    • char: 16 bits, armazena um único caractere Unicode.

Tipos de Referência:

  1. String:

    • String: armazena uma sequência de caracteres.
  2. Objetos:

    • Tipos de dados personalizados criados por você ou disponíveis em bibliotecas, como classes, interfaces, etc.

Exemplo de Uso:

public class DataTypesExample {
    public static void main(String[] args) {
        // Tipos primitivos
        byte idade = 30;
        int numero = 12345;
        double preco = 99.99;
        boolean ehVerdade = true;
        char letra = 'A';

        // Strings
        String nome = "João";

        // Saída no console
        System.out.println("Idade: " + idade);
        System.out.println("Número: " + numero);
        System.out.println("Preço: " + preco);
        System.out.println("É verdade? " + ehVerdade);
        System.out.println("Letra: " + letra);
        System.out.println("Nome: " + nome);
    }
}

Variáveis

Em Java, as variáveis são locais de armazenamento que contêm dados manipulados pelo programa. Cada variável tem um tipo de dado associado e um nome que a identifica dentro do escopo em que foi declarada. Aqui estão os principais pontos sobre variáveis em Java:

Declaração de Variáveis:

  1. Sintaxe básica:

    • Para declarar uma variável em Java, você especifica o tipo de dado seguido pelo nome da variável e, opcionalmente, um valor inicial.

    Exemplo:

    int idade; // Declaração de uma variável inteira
    double preco = 99.99; // Declaração de uma variável double com valor inicial
  2. Inicialização:

    • As variáveis podem ser inicializadas quando são declaradas ou posteriormente no código.

    Exemplo:

    int numero; // Declaração
    numero = 10; // Inicialização posterior

Tipos de Variáveis:

  1. Variáveis Primitivas:

    • Armazenam valores primitivos diretos.
    • Exemplos: int, double, boolean, char, byte, short, long, float.
  2. Referência a Objetos:

    • Referenciam objetos em memória.
    • Exemplos: String, objetos de classes personalizadas, interfaces.

Regras para Nomes de Variáveis:

  1. Podem conter letras, números, cifrões $ e sublinhados _.
  2. Devem começar com uma letra, cifrão $ ou sublinhado _.
  3. Não podem conter espaços em branco.
  4. Não podem ser palavras-chave reservadas.

Exemplo de Uso:

public class VariaveisExemplo {
    public static void main(String[] args) {
        // Declaração e inicialização de variáveis
        int idade = 30;
        double altura = 1.75;
        String nome = "Maria";

        // Uso das variáveis
        System.out.println("Nome: " + nome);
        System.out.println("Idade: " + idade);
        System.out.println("Altura: " + altura);
    }
}

As variáveis em Java são usadas para armazenar dados temporários ou permanentes, dependendo de suas necessidades. Elas desempenham um papel fundamental na manipulação e armazenamento de informações durante a execução do programa.

Estruturas Condicionais

Em Java, as estruturas condicionais permitem que você tome decisões com base em condições específicas. As estruturas mais comuns são if, else if e else.

if:

O if verifica se uma condição é verdadeira e executa um bloco de código se a condição for verdadeira.

int numero = 10;

if (numero > 0) {
    System.out.println("O número é positivo.");
}

if - else:

O if e else são usados juntos para fornecer um caminho alternativo caso a condição do if seja falsa.

int numero = -5;

if (numero > 0) {
    System.out.println("O número é positivo.");
} else {
    System.out.println("O número não é positivo.");
}

if - else if - else:

Você pode encadear várias condições usando else if para verificar diferentes cenários.

int numero = 0;

if (numero > 0) {
    System.out.println("O número é positivo.");
} else if (numero < 0) {
    System.out.println("O número é negativo.");
} else {
    System.out.println("O número é zero.");
}

Operador Ternário:

Outra maneira de fazer uma operação condicional é usando o operador ternário ? :.

int numero = 10;
String resultado = (numero % 2 == 0) ? "Par" : "Ímpar";
System.out.println(resultado); // Saída: Par

Switch:

O switch é usado para selecionar um dos muitos blocos de código para execução, dependendo do valor de uma expressão específica.

int diaDaSemana = 3;
String nomeDia;

switch (diaDaSemana) {
    case 1:
        nomeDia = "Domingo";
        break;
    case 2:
        nomeDia = "Segunda-feira";
        break;
    // E assim por diante para outros casos
    default:
        nomeDia = "Dia inválido";
}

System.out.println("Hoje é " + nomeDia);

Essas estruturas condicionais permitem que você controle o fluxo do seu programa com base em diferentes condições, o que é essencial para a lógica de tomada de decisões.

Arrays

Em Java, os arrays são estruturas de dados que armazenam um conjunto fixo de elementos do mesmo tipo.

Declaração de um Array:

// Declaração de um array de inteiros com 5 elementos
int[] numeros; // ou int numeros[];

Inicialização de um Array:

Há várias maneiras de inicializar um array em Java:

  1. Inicialização direta:

    int[] numeros = {1, 2, 3, 4, 5}; // Inicialização direta com os valores
  2. Inicialização com o operador new:

    int[] numeros = new int[5]; // Inicialização com um array de tamanho 5

Acesso aos Elementos do Array:

Os elementos do array são acessados usando um índice baseado em zero.

int[] numeros = {1, 2, 3, 4, 5};
int primeiroNumero = numeros[0]; // Acessando o primeiro elemento (índice 0)
int terceiroNumero = numeros[2]; // Acessando o terceiro elemento (índice 2)

Iterando sobre um Array:

Para percorrer os elementos de um array, você pode usar um loop for ou for-each:

  1. Loop for:

    int[] numeros = {1, 2, 3, 4, 5};
    
    for (int i = 0; i < numeros.length; i++) {
        System.out.println(numeros[i]);
    }
  2. Loop for-each:

    int[] numeros = {1, 2, 3, 4, 5};
    
    for (int numero : numeros) {
        System.out.println(numero);
    }

Arrays Multidimensionais:

Java também suporta arrays multidimensionais, como arrays bidimensionais.

// Declaração e inicialização de um array bidimensional (matriz)
int[][] matriz = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

int elemento = matriz[1][2]; // Acessando o elemento na segunda linha e terceira coluna (índices 1 e 2)

Os arrays em Java têm um tamanho fixo após a inicialização, e o tamanho deve ser especificado no momento da criação ou inicialização. Manipular arrays oferece muitas possibilidades para armazenar e acessar dados de forma estruturada em seus programas Java.

ArrayList

ArrayList em Java é uma implementação da interface List que fornece uma estrutura de dados dinâmica para armazenar elementos. Ao contrário de arrays convencionais, ArrayList pode crescer ou encolher automaticamente para acomodar a adição ou remoção de elementos.

Importando a Classe ArrayList:

import java.util.ArrayList;

Criando um ArrayList:

ArrayList<String> listaDeNomes = new ArrayList<>();

Adicionando Elementos:

listaDeNomes.add("Alice");
listaDeNomes.add("Bob");
listaDeNomes.add("Carol");

Acessando Elementos:

String primeiroNome = listaDeNomes.get(0); // Acessando o primeiro elemento (índice 0)

Iterando sobre um ArrayList:

for (String nome : listaDeNomes) {
    System.out.println(nome);
}

Removendo Elementos:

listaDeNomes.remove("Bob"); // Remove o elemento "Bob"
// ou
listaDeNomes.remove(1); // Remove o elemento no índice 1

Verificando o Tamanho do ArrayList:

int tamanho = listaDeNomes.size(); // Retorna o tamanho da lista

Arrays vs. ArrayList:

Arrays têm um tamanho fixo após a criação, enquanto ArrayList pode crescer ou diminuir dinamicamente. A escolha entre eles depende das necessidades do seu programa. Se você precisar de uma estrutura de dados flexível que possa ser modificada facilmente, o ArrayList é mais conveniente. Se precisar de uma estrutura com tamanho fixo, um array convencional pode ser mais apropriado.

Tipagem no ArrayList:

O ArrayList é genérico, o que significa que você pode especificar o tipo de elementos que ele irá conter entre os sinais de menor e maior <tipo> (por exemplo, ArrayList<String> para uma lista de strings). Isso ajuda a evitar erros de tipo durante a compilação e oferece mais segurança de tipo durante a execução.

Loops

Em Java, existem várias maneiras de criar loops para executar um bloco de código repetidamente.

1. Loop for:

O loop for é usado quando você sabe exatamente quantas vezes deseja iterar.

for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

2. Loop while:

O loop while é usado quando você quer executar um bloco de código enquanto uma condição específica for verdadeira.

int contador = 0;
while (contador < 5) {
    System.out.println(contador);
    contador++;
}

3. Loop do-while:

O loop do-while é semelhante ao while, mas garante que o bloco de código seja executado pelo menos uma vez, mesmo se a condição for falsa.

int contador = 0;
do {
    System.out.println(contador);
    contador++;
} while (contador < 5);

4. Loop for-each (para iterar em arrays e coleções):

O loop for-each é usado para percorrer coleções (como arrays, listas) de maneira simples e eficiente.

int[] numeros = {1, 2, 3, 4, 5};
for (int numero : numeros) {
    System.out.println(numero);
}

Controle de Fluxo:

Dentro dos loops, você pode usar break para sair do loop prematuramente e continue para pular a iteração atual e continuar para a próxima.

Exemplo de Aninhamento de Loops:

É possível aninhar loops, ou seja, colocar um loop dentro de outro.

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        System.out.println("i: " + i + ", j: " + j);
    }
}

Escolhendo o Tipo de Loop:

  • Use for quando souber o número de iterações.
  • Use while quando a condição de término não estiver relacionada ao número de iterações.
  • Use do-while quando quiser garantir que o bloco de código seja executado pelo menos uma vez.
  • Use for-each para percorrer coleções de elementos.

Casting

O casting em Java é a conversão explícita de um tipo de dado para outro. Ele é utilizado quando você deseja converter um tipo de dado em outro tipo compatível. Existem dois tipos de casting em Java: casting implícito e casting explícito.

Casting Implícito:

Ocorre quando não há perda de dados ao converter de um tipo menor para um tipo maior. Isso é feito automaticamente pelo Java.

Exemplo de casting implícito:

int inteiro = 10;
double decimal = inteiro; // Conversão implícita de int para double

Casting Explícito:

Ocorre quando há uma potencial perda de dados ao converter de um tipo maior para um tipo menor. Isso requer uma sintaxe especial para indicar que você está ciente da possível perda de precisão.

Exemplo de casting explícito:

double decimal = 10.5;
int inteiro = (int) decimal; // Conversão explícita de double para int

Regras do Casting Explícito:

  • Para realizar o casting explícito, você coloca o tipo entre parênteses antes da variável que deseja converter.
  • O casting explícito pode causar perda de dados se o valor do tipo maior não puder ser representado pelo tipo menor.
  • Ao converter um tipo maior para um tipo menor, você pode perder informações de precisão ou até mesmo valores significativos.
int numero = 130;
byte valor = (byte) numero; // O valor será -126 devido ao estouro do intervalo de um byte (-128 a 127)

Considerações:

  • O casting em Java pode ser útil ao trabalhar com diferentes tipos de dados, mas é importante estar ciente de possíveis perdas de precisão ou estouro de valores ao realizar conversões.
  • Certifique-se de usar o casting com cuidado para evitar problemas de compatibilidade de tipo e perda de dados importantes durante as conversões.

Classes

Em Java, as classes são blocos de construção fundamentais usados para criar objetos. Elas servem como modelos ou planos para criar instâncias (objetos) que possuem características e comportamentos específicos.

Exemplo de Classe:

Vamos criar uma classe Pessoa que representa pessoas com atributos como nome e idade, e métodos para acessar e modificar esses atributos.

// Definição da classe Pessoa
public class Pessoa {
    // Atributos (variáveis de instância)
    private String nome;
    private int idade;

    // Construtor (método especial para criar objetos)
    public Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }

    // Métodos para acessar e modificar os atributos (getters e setters)
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getIdade() {
        return idade;
    }

    public void setIdade(int idade) {
        this.idade = idade;
    }

    // Outros métodos da classe Pessoa
    public void imprimirDetalhes() {
        System.out.println("Nome: " + nome + ", Idade: " + idade);
    }
}

Uso da Classe:

Agora que temos a classe Pessoa, podemos criar objetos (instâncias) dessa classe e utilizar seus métodos e atributos.

public class Main {
    public static void main(String[] args) {
        // Criando objetos (instâncias) da classe Pessoa
        Pessoa pessoa1 = new Pessoa("Alice", 30);
        Pessoa pessoa2 = new Pessoa("Bob", 25);

        // Usando métodos da classe Pessoa
        pessoa1.imprimirDetalhes(); // Saída: Nome: Alice, Idade: 30
        pessoa2.imprimirDetalhes(); // Saída: Nome: Bob, Idade: 25

        // Modificando atributos usando os setters
        pessoa1.setIdade(35);
        pessoa2.setNome("Robert");

        pessoa1.imprimirDetalhes(); // Saída: Nome: Alice, Idade: 35
        pessoa2.imprimirDetalhes(); // Saída: Nome: Robert, Idade: 25
    }
}

Principais Conceitos:

  • Atributos: Representam as características dos objetos.
  • Métodos: Definem o comportamento dos objetos.
  • Construtor: Método especial para inicializar objetos.
  • Encapsulamento: O uso de modificadores de acesso (private, public, protected) para controlar o acesso aos atributos da classe.
  • Instância: Criação de objetos a partir de uma classe usando o operador new.

As classes em Java permitem criar estruturas complexas e modulares, facilitando a criação e organização de programas. Elas são a base da orientação a objetos em Java e são essenciais para a construção de aplicações robustas e reutilizáveis.

Objectos

Em Java, um objeto é uma instância de uma classe. Uma classe é um modelo ou um plano para criar objetos que possuem atributos e comportamentos específicos. Os objetos são criados a partir de classes usando o operador new.

Criando Objetos:

Para criar um objeto, você precisa usar a palavra-chave new seguida do nome da classe e dos parênteses para chamar o construtor da classe.

Exemplo de criação de objetos:

// Classe Pessoa
public class Pessoa {
    private String nome;

    public Pessoa(String nome) {
        this.nome = nome;
    }

    public void imprimirNome() {
        System.out.println("Nome: " + nome);
    }
}

// Criando objetos da classe Pessoa
Pessoa pessoa1 = new Pessoa("Alice");
Pessoa pessoa2 = new Pessoa("Bob");

Atributos e Métodos:

Os objetos têm atributos (variáveis de instância) que representam suas características e métodos que definem seu comportamento.

// Atributo nome na classe Pessoa
private String nome;

// Método imprimirNome na classe Pessoa
public void imprimirNome() {
    System.out.println("Nome: " + nome);
}

Acesso aos Atributos e Métodos:

Você pode acessar os atributos e métodos de um objeto usando o operador ponto (.).

pessoa1.imprimirNome(); // Saída: Nome: Alice
pessoa2.imprimirNome(); // Saída: Nome: Bob

Instâncias Únicas:

Cada objeto é uma instância única de sua classe. Isso significa que os objetos criados a partir da mesma classe podem ter valores diferentes para seus atributos.

pessoa1.setNome("Carol");
pessoa1.imprimirNome(); // Saída: Nome: Carol
pessoa2.imprimirNome(); // Saída: Nome: Bob

Referências de Objetos:

As variáveis que guardam objetos armazenam referências para esses objetos na memória, não os objetos em si.

Pessoa pessoa3 = pessoa1;
pessoa3.setNome("Daniel");
pessoa1.imprimirNome(); // Saída: Nome: Daniel (alterado através da referência pessoa3)

Encapsulamento:

É uma prática comum em Java encapsular os atributos de um objeto usando modificadores de acesso (private, public, protected) e fornecer métodos públicos (getters e setters) para acessá-los e modificá-los.

Os objetos em Java são fundamentais para a programação orientada a objetos, permitindo a criação de estruturas complexas, modulares e reutilizáveis. Cada objeto representa uma entidade distinta com seu próprio estado e comportamento.

Constructores

Em Java, um construtor é um método especial usado para inicializar objetos quando são criados a partir de uma classe. Ele possui o mesmo nome da classe e não tem tipo de retorno.

Propósito do Construtor:

  • Inicialização de Objetos: Um construtor é chamado automaticamente quando um objeto é criado usando a palavra-chave new. Ele inicializa o estado do objeto definindo valores para seus atributos ou realizando outras inicializações necessárias.

Tipos de Construtores:

  1. Construtor Padrão (Default): Se uma classe não define nenhum construtor, o Java fornece um construtor padrão sem parâmetros. Esse construtor inicializa os valores padrão para os atributos da classe.
public class MinhaClasse {
    // Construtor padrão (default)
    public MinhaClasse() {
        // Inicialização padrão, se necessário
    }
}
  1. Construtores Personalizados: Você pode definir seus próprios construtores com diferentes parâmetros para inicializar objetos de maneiras específicas.
public class Pessoa {
    private String nome;
    private int idade;

    // Construtor personalizado com parâmetros
    public Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }
}

Uso dos Construtores:

  • Chamada Automática: O construtor é chamado automaticamente quando um objeto é criado usando new NomeDaClasse().
Pessoa pessoa = new Pessoa("Alice", 30); // Chama o construtor personalizado

Sobrecarga de Construtores:

Você pode ter múltiplos construtores na mesma classe com diferentes listas de parâmetros. Isso é chamado de sobrecarga de construtores.

public class Pessoa {
    private String nome;
    private int idade;

    // Construtor com um parâmetro
    public Pessoa(String nome) {
        this.nome = nome;
    }

    // Construtor com dois parâmetros
    public Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }
}

Uso de this no Construtor:

  • this é usado para referenciar os atributos da própria classe quando há ambiguidade com os parâmetros do construtor.

Finalidade do Construtor:

  • Inicializar Atributos: Definir valores iniciais para os atributos da classe.
  • Garantir Valores Iniciais: Garantir que o objeto comece em um estado válido.
  • Personalizar Criação de Objetos: Oferecer diferentes maneiras de criar objetos com valores específicos.

Os construtores em Java são úteis para inicializar objetos de uma classe de acordo com suas necessidades específicas, permitindo uma inicialização adequada de seus atributos.

Modificadores

Em Java, os modificadores são palavras-chave que fornecem controle de acesso e controle de outras características em classes, métodos e variáveis. Eles ajudam a definir a visibilidade, acessibilidade e comportamento de diferentes elementos dentro do código.

Modificadores de Acesso:

  1. public:

    • Acesso irrestrito. Pode ser acessado de qualquer lugar.
  2. private:

    • Acesso restrito à própria classe. Não pode ser acessado de fora da classe.
  3. protected:

    • Acesso permitido dentro do mesmo pacote e por subclasses, mesmo que estejam em pacotes diferentes.
  4. (default / sem modificador):

    • Acesso permitido somente dentro do mesmo pacote. Não pode ser acessado por classes de pacotes diferentes.

Modificadores de Outros Comportamentos:

  1. static:

    • Indica que um método ou variável pertence à classe, não a instâncias individuais.
  2. final:

    • Indica que um método, variável ou classe não pode ser alterado ou estendido.
  3. abstract:

    • Aplicado a classes ou métodos, indica que a classe não pode ser instanciada (somente suas subclasses) ou que um método precisa ser sobrescrito por subclasses.
  4. synchronized:

    • Usado para controlar o acesso concorrente a métodos ou blocos de código, garantindo que apenas uma thread pode acessar por vez.
  5. volatile:

    • Usado para variáveis que podem ser acessadas por múltiplas threads, indicando que o valor da variável pode ser alterado por threads externas.
  6. transient:

    • Usado para indicar que um campo de uma classe não deve ser serializado durante o processo de serialização.

Exemplo de Uso:

public class Exemplo {
    private int variavelPrivada;
    public static final double PI = 3.14;
    
    public void metodoPublico() {
        // Código do método
    }
    
    protected void metodoProtegido() {
        // Código do método
    }
    
    static synchronized void metodoEstaticoSincronizado() {
        // Código do método
    }
}

Considerações:

  • Os modificadores em Java oferecem controle sobre o encapsulamento, herança, acesso e outros aspectos do código, promovendo a segurança e modularidade.
  • Escolher o modificador correto depende das necessidades de design e segurança do seu código. Por exemplo, garantir o encapsulamento usando private e permitir herança usando protected.
  • O uso adequado de modificadores ajuda a criar classes e métodos mais seguros, facilitando a manutenção e o desenvolvimento de código em equipe.

Herança

Em Java, herança é um dos princípios fundamentais da programação orientada a objetos, permitindo que uma classe herde atributos e métodos de outra classe. Isso facilita a reutilização de código e a criação de hierarquias entre classes.

Sintaxe da Herança:

// Classe Pai (ou Superclasse)
public class Animal {
    public void fazerSom() {
        System.out.println("Barulho genérico de um animal.");
    }
}

// Classe Filha (ou Subclasse)
public class Cachorro extends Animal {
    public void latir() {
        System.out.println("Au au!");
    }
}
  • Animal é a classe pai (superclasse) que contém o método fazerSom.
  • Cachorro é a classe filha (subclasse) que herda de Animal e adiciona o método latir.

Palavra-chave extends:

  • extends é usada para criar uma relação de herança entre as classes.
public class Cachorro extends Animal {
    // ...
}

Herança de Atributos e Métodos:

  • A classe filha herda todos os atributos e métodos não privados da classe pai.
  • A classe filha pode adicionar novos métodos e atributos, além de sobrescrever métodos existentes, se necessário.

Exemplo de Uso:

public class Main {
    public static void main(String[] args) {
        Cachorro meuCachorro = new Cachorro();
        meuCachorro.fazerSom(); // Saída: Barulho genérico de um animal.
        meuCachorro.latir();    // Saída: Au au!
    }
}

Sobrescrita de Métodos (Override):

  • Uma subclasse pode substituir (sobrescrever) um método da superclasse para fornecer sua própria implementação.
public class Cachorro extends Animal {
    @Override
    public void fazerSom() {
        System.out.println("Au au! (sobrescrito)");
    }
}

Considerações sobre Herança:

  • A herança é uma relação “é um” (ex: um cachorro é um animal).
  • Ajuda na reutilização de código, facilitando a criação de hierarquias de classes e evitando repetição.
  • Uma classe pode herdar de apenas uma superclasse direta (Java não suporta herança múltipla de classes).
  • Garantir que a relação de herança é lógica e que a subclasse realmente é uma versão especializada da superclasse é essencial para um design de classe sólido.

A herança em Java é um conceito poderoso que permite a criação de hierarquias de classes, facilitando a reutilização e a extensão de funcionalidades. No entanto, deve ser usado com cuidado para manter um design de código claro e coeso.

Polimorfismo

O polimorfismo é um conceito fundamental da programação orientada a objetos que permite que objetos de classes diferentes sejam tratados como objetos de uma classe comum. Em Java, o polimorfismo é implementado por meio de dois mecanismos: polimorfismo de sobrecarga (métodos com o mesmo nome em uma classe, mas com diferentes parâmetros) e polimorfismo de sobreposição (métodos em classes relacionadas que têm a mesma assinatura).

Polimorfismo de Sobreposição (Override):

Na sobreposição, uma classe filha fornece uma implementação específica para um método que já está definido em sua classe pai. Isso permite que um objeto da classe filha seja tratado como um objeto da classe pai, mas com a execução do método específico da classe filha.

Exemplo:

// Classe Pai (Superclasse)
class Animal {
    public void fazerSom() {
        System.out.println("Barulho genérico de um animal.");
    }
}

// Classe Filha (Subclasse) que sobrepõe o método fazerSom
class Cachorro extends Animal {
    @Override
    public void fazerSom() {
        System.out.println("Au au!");
    }
}

Agora você pode fazer algo como:

Animal meuCachorro = new Cachorro();
meuCachorro.fazerSom(); // Saída: Au au!

Polimorfismo de Sobreposição com Interfaces:

Interfaces em Java também suportam polimorfismo. Se uma classe implementa uma interface, você pode tratar objetos dessa classe como objetos da interface.

// Interface
interface Barulhento {
    void fazerSom();
}

// Implementação da Interface
class Cachorro implements Barulhento {
    @Override
    public void fazerSom() {
        System.out.println("Au au!");
    }
}

Polimorfismo de Sobrecarga:

Na sobrecarga, vários métodos podem ter o mesmo nome, mas com diferentes listas de parâmetros. Isso permite que você chame o mesmo método com diferentes tipos de argumentos.

Exemplo:

class Calculadora {
    public int somar(int a, int b) {
        return a + b;
    }

    public double somar(double a, double b) {
        return a + b;
    }
}

A chamada pode ser feita de maneira polimórfica:

Calculadora calc = new Calculadora();
int resultadoInt = calc.somar(5, 10);
double resultadoDouble = calc.somar(3.5, 2.7);

Vantagens do Polimorfismo:

  • Flexibilidade: Permite que o mesmo código trate objetos de classes diferentes de maneira uniforme.
  • Manutenibilidade: Facilita a adição de novas classes sem alterar o código existente.
  • Legibilidade: Torna o código mais legível e expressivo.

O polimorfismo é uma característica poderosa da programação orientada a objetos que promove a flexibilidade e reutilização de código. É uma prática comum em Java e é usado em conjunto com conceitos como herança e interfaces para criar sistemas mais modulares e extensíveis.

Parabéns por chegar ao fim da leitura! É uma conquista e tanto ter dedicado tempo e esforço para aprender sobre conceitos básicos de Java.

Lembre-se também de se manter atualizado. A tecnologia está em constante evolução, e novos conceitos, ferramentas e técnicas estão sempre surgindo. Acompanhe blogs, fóruns, conferências e cursos online para se manter informado sobre as tendências e avanços na área.

Em resumo, continue aprendendo, praticando e se desafiando. A programação é uma jornada emocionante e cheia de possibilidades. Boa sorte em suas futuras explorações na área da tecnologia!

Por Francisco Inoque 🫶


Headshot of Francisco Inoque

Hello, I'm Francisco Inoque, an experienced Back-End Developer with expertise in Node.js, Go, and Python. I thrive on solving complex development challenges and am eager to contribute to innovative projects. Let's connect and discuss how I can help you achieve your goals efficiently!