image

Bootcamps ilimitados e +650 cursos pra sempre

60
%OFF
Article image
Arthur Carneiro
Arthur Carneiro21/10/2025 12:03
Compartilhe

Fundamentos de Java: Orientação a Objetos com 🍥Naruto

    Quando falamos de Fundamentos de Java a Orientação a Objetos (OO) é reconhecida como um dos pilares mais importantes da programação moderna. com tantas explicações já existentes sobre esse assunto eu quero abortar algo diferente usando a técnica de Feynman e baseado em um vídeo que vi a muito tempo vamos desvendar os mistérios de Java, usando o rico universo de Naruto, onde a complexidade dos Clãs e das técnicas ninjas nos ajudará a ilustrar cada conceito da POO.

    Neste artigo, exploraremos a arquitetura da POO em Java, desde seus componentes fundamentais até os quatro pilares essenciais, utilizando exemplos de código inspirados nos ninjas de Konoha.

    image

    🍥 Introdução

    Java não é apenas uma linguagem de programação de alto nível; é uma plataforma completa, conhecida por ser robusta, segura e multiplataforma.A POO é o paradigma central de Java. Ela surgiu como uma solução para a complexidade da programação estruturada, onde grandes programas se tornavam difíceis de manter e entender.

    Em vez de seguir uma série de instruções ("receita"), a POO estrutura o programa como uma rede de entidades independentes que trabalham juntas: os objetos.Pense no Time 7. Cada membro (Naruto, Sasuke, Sakura) tem um papel, mas eles interagem para cumprir missões.

    Compreender a POO em Java é imprescindível para escrever qualquer software significativo. É a maneira como os sistemas reais de software são fatorados em partes independentes.

    🗡️O que é Orientação a Objetos (OO)

    Orientação a Objetos é um padrão conceitual que orienta a implementação, modelando objetos do mundo real.Um objeto é uma abstração, uma entidade que se pode reconhecer, composta por dados e operações sobre esses dados.

    Um programa orientado a objetos é estruturado como uma **comunidade de objetos** que interagem, onde cada objeto oferece um serviço ou realiza uma ação.

    OO utiliza a abstração, o uso de classes encapsuladas, a comunicação por mensagens e a hierarquia de classes, culminando no polimorfismo.

    • Características (Atributos):São as variáveis que armazenam informações relevantes, como nome ou força.
    • Comportamentos (Métodos):São as ações ou serviços executados pelo objeto, representados por verbos, como atacar ou defender.

    No universo ninja, um Ninja é um objeto. Ele tem características (como o nível de Chakra ou a Aldeia) e comportamentos (como Correr ou lançar Jutsu).

    image

    🌀Componentes Fundamentais da OO

    Classes

     Classe é o molde, o modelo, ou a descrição formal. Ela define a estrutura estática do sistema, delineando quais atributos e métodos os futuros objetos terão.

    Em nossa analogia, a classe é o Ninja.

    • O Ninja(Classe) define que seus membros possuirão o nome,aldeia e chakra e o comportamento correr.

    As classes em Java geralmente contêm atributos (private) e métodos (public) que definem o encapsulamento.

    Exemplo de estrutura da Classe base Ninja:

    /**
     * A Classe Ninja define o molde básico para todos os shinobis.
     */
    public class Ninja {
      // Atributos (características)
      private String nome;
      private String aldeia;
      private int chakra;
    
    
      // Métodos (comportamentos)
      public void correr {
          System.out.println(nome + " está correndo em alta velocidade!");
      }
      public void jogarKunai {
          System.out.println(nome + " está jogando uma kunai");
      }
    }
    

    Tipicamente, cada classe é implementada em um arquivo fonte separado, cujo nome deve ser o mesmo da classe (ex.: Ninja.java).

    Objetos

    O Objeto é a instância concreta da classe, ou seja, a materialização do molde. É uma entidade que possui atributos (estado) e comportamento.

    • Sasuke Uchiha é um objeto (instância) do Clã Uchiha.
    • Rock Lee é um objeto que foca em Taijutsu.

    A criação do objeto ocorre pelo processo de instanciação, usando o operador new.

    Quando um objeto é criado, a memória é alocada. Os atributos não inicializados recebem valores padrão (0 para inteiros, null para objetos).

    Exemplo de Instanciação e Manipulação:

    // Criando objetos
    Ninja naruto = new Ninja("Naruto Uzumaki", "Konoha", 100);
    Ninja sasuke = new Ninja("Sasuke Uchiha", "Konoha", 80);
    
    
    // Chamando o comportamento
    naruto.correr();
    // Saída: "Naruto Uzumaki está correndo em alta velocidade!"
    

    image

    Em Java, uma variável de objeto armazena uma **referência** para o objeto na memória. Se uma referência é copiada para outra variável (ninja2 = ninja1), ambas apontam para o mesmo objeto. Alterar um afeta o outro.

    🪃Construtores

    O Construtor é crucial para definir o estado inicial do objeto logo após sua instanciação. Ele garante que o objeto "nasça" com atributos válidos.

    Características do Construtor:

    • Possui o mesmo nome da classe (Ninja()).
    • Não tem tipo de retorno (nem void).
    • Pode receber ou não parâmetros.

    Se a classe não tiver nenhum construtor definido, Java fornece um construtor default sem argumentos.

    Exemplo de Construtor para a classe Ninja:

    public class Ninja {
      // Atributos privados
      private String nome;
      private String aldeia;
      private int chakra;
    
    
      // Construtor: Inicializa o objeto com valores passados como parâmetro
      public Ninja(String nome, String aldeia, int chakra) {
          this.nome = nome;
          this.aldeia = aldeia;
          this.chakra = chakra;
          // 'this.' garante que referenciamos o atributo da classe
      }
    }
    

    Sobrecarga de Construtores permite diferentes maneiras de inicializar o objeto.

    Podemos ter um construtor completo e um simplificado. Para evitar repetição de código (que não é uma boa prática), usamos this() para chamar o construtor mais completo.

    public class Ninja {
      // Construtor completo:
      public Ninja(String nome, String aldeia, int chakra) { /* ... */ }
    
    
      // Construtor Sobrecarrregado: Cria um Jinchuuriki Uzumaki padrão
      public Ninja(String nome) {
          // Reutiliza o construtor completo com valores padrão
          this(nome, "Konoha", 150);
      }
    }
    

    image

    Os Quatro Pilares da Orientação a Objetos

    1. Encapsulamento

    O Encapsulamento é a prática de proteger os dados internos do objeto, escondendo os detalhes de funcionamento ("caixa preta"). A interface externa (o que é público) é a única forma de interagir.

    O objetivo é garantir a segurança dos atributos contra alterações indevidas.

    Em Java, o encapsulamento é realizado definindo atributos como private.

    Para permitir a leitura e alteração controlada, usamos os métodos Getters (retornam o valor) e Setters (modificam o valor).

    Na analogia do Chakra, não é necessário saber o mecanismo interno de moldagem do chakra (private), mas sim como invocar o Jutsu(public).

    Exemplo de Getter e Setter para Chakra:

    public class Ninja {
      private int chakra; // Atributo encapsulado
    
    
      // Getter para ler o nível de Chakra
      public int getChakra() {
          return chakra;
      }
    
    
      // Setter (Mutator Method) para modificar o Chakra
      public void setChakra(int novoChakra) {
          // Regra de Negócio: Chakra nunca pode ser negativo
          if (novoChakra >= 0) {
              this.chakra = novoChakra;
          } else {
              System.out.println("O Chakra não pode ser negativo!");
          }
      }
    }
    

    image

    2. Herança

    A Herança é um relacionamento hierárquico, indicando que uma classe é um tipo de outra classe (relação "É um").

    É o mecanismo que permite que a subclasse (filha) herde os atributos e métodos da superclasse (pai), promovendo a reutilização de código.

    • Um Uchiha (subclasse) é um Ninja (superclasse).

    Utilizamos a palavra-chave extends em Java para implementar a herança.

    Exemplo de Herança: Uzumaki estendendo Ninja.

    public class Uzumaki extends Ninja { // Herda nome, aldeia, chakra
      private boolean temBijuu; // Característica única do clã Uzumaki
    
    
      public Uzumaki(String nome, String aldeia, int chakra, boolean bijuu) {
          super(nome, aldeia, chakra); // Chama o construtor da classe pai
          this.temBijuu = bijuu;
      }
    
    
      public void ataqueBase() { // Comportamento único
          if (chakra>50) {
              System.out.println(getNome() + ": fez o rasengan");
          }
      }
    }
    

    Se o objeto Uzumaki for instanciado, ele terá acesso tanto aos métodos de Ninja (como correr) quanto aos seus próprios (como ataqueBase).

    image

    3. Polimorfismo

    Polimorfismo significa a capacidade de um método ter múltiplas formas de execução. O mesmo nome de método pode se comportar de maneira diferente em contextos distintos.

    Sobrescrita (_Overriding_)

    Sobrescrita ocorre quando uma subclasse altera a implementação de um método que herdou do pai. A assinatura (nome e parâmetros) deve ser a mesma.

    • Todos os Ninjas têm um método atacarBase().
    • O Uchiha sobrescreve atacarBase() para, em vez de lançar uma Kunai, usar um Jutsu de fogo (Katon).

    Usamos a anotação @Override para indicar que estamos sobrescrevendo o método da superclasse.

    Exemplo de Sobrescrita:

    // Na subclasse Uchiha (que estende Ninja)
    @Override
    public void ataqueBase() {
      // Comportamento específico do Uchiha, sobrescrevendo o Ninja base
      System.out.println(getNome() + " usou Katon: Goukakyuu no Jutsu!");
    }
    // Na subclasse Uzumaki (que estende Ninja)
    @Override
    public void ataqueBase() {
      // Comportamento específico do Uzumaki
      System.out.println(getNome() + " usou Fuuton: Rasengan!");
    }
    

    image

    Quando chamamos naruto.atacarBase() e sasuke.atacarBase(), o código é o mesmo, mas o resultado é diferente, dependendo do tipo real do objeto (Uzumaki ou Uchiha).

    Sobrecarga (_Overloading_)

    Sobrecarga permite ter múltiplos métodos com o mesmo nome dentro da mesma classe, desde que tenham assinaturas diferentes (diferentes tipos ou número de parâmetros).

    Exemplo de Sobrecarga para o método Atacar:

    public class Ninja {
      // 1. Atacar padrão (Taijutsu)
      public void atacar() {
          System.out.println(getNome() + " utilizou rasengan comum.");
      }
    
    
      // 2. Sobrecarga: Atacar com nível de Chakra (diferente parâmetro)
      public void atacar(int nivelChakra) {
          if (nivelChakra > 50) {
              System.out.println(getNome() + " lançou um rasengan gigante");
          } else {
              System.out.println(getNome() + " usou um rasengan comum.");
          }
      } 
    

    image

    O Java resolve qual método chamar em tempo de compilação, baseando-se no tipo e na quantidade de argumentos passados.

    4. Abstração

    Abstração é focar no que é relevante, ignorando os detalhes não essenciais. É o processo de criar modelos concisos do mundo real.

    Em POO, a abstração é fundamental na fase de projeto.

    Classes Abstratas e métodos abstratos são usados para enforce a abstração em código.

    Uma Classe Abstrata é um modelo genérico (como Personagem ou Jutsu) que não deve ser instanciado, mas que define uma base comum para herança.

    Se a classe Personagem for abstract, o compilador impede que se crie um objeto diretamente dela.

    Um método abstrato não tem corpo e força todas as classes filhas (concretas) a fornecerem sua própria implementação.

    Exemplo de Abstração:

    public abstract class Ninja {
      // ... Atributos
    
    
      // Método abstrato: Força todos os Ninjas a definir seu golpe principal
      public abstract void usarJutsuPrincipal(); // Não tem implementação aqui
    }
    
    
    // A subclasse deve implementar o método:
    public class Naruto extends Ninja {
      @Override
      public void usarJutsuPrincipal() {
          System.out.println("Kage Bunshin no Jutsu!"); // Implementação do Naruto
      }
    }
    

    image

    🐸Interfaces em Java

    Interfaces são tipos de referência que definem um contrato de comportamento, especificando um conjunto de métodos que uma classe promete implementar.

    Diferente da herança (singular), uma classe pode implementar múltiplas interfaces, assumindo múltiplos papéis.

    Interfaces são ideais para modelar capacidades.

    • Capacidade de cura (Ninjutsu Médico).
    • Capacidade de invocar bestas (Kuchiyose no Jutsu).

    Exemplo de Interface:

    public interface Invocador {
      // Métodos são implicitamente public e abstract
      void invocarBesta(String nomeBesta);
    }
    
    
    // Kakashi pode ser um Invocador (implementa a interface)
    public class Kakashi extends Ninja implements Invocador {
      // Kakashi é obrigado a fornecer o código para invocarBesta
      @Override
      public void invocarBesta(String nomeBesta) {
          SSystem.out.println(nome + " invocou " + nomeBesta + ", o cão ninja!");
      }
    }
    

    image

    🎌 Classes e Métodos Estáticos

    A palavra-chave static indica que um atributo ou método pertence à Classe, não a uma instância de objeto específica.

    Atributos Estáticos (Atributos de Classe)

    Estes atributos são compartilhados por todas as instâncias da classe; existe apenas uma cópia.

    São frequentemente usados para constantes (com o modificador final) ou para manter contadores.

    Analogia: O nome da Aldeia da Folha (Konoha) é um valor que não muda para nenhum ninja nascido lá, sendo uma constante estática.

    public class Vila {
      // Constante estática, acessada pela classe Vila.VILA_PADRAO
      public static final String NOME_VILA = "Konoha Gakure";
    
    
      private static int totalPopulacaoNinja = 0; // Atributo compartilhado
    
    
      public Vila() {
          totalPopulacaoNinja++;
      }
    }
    

    Atributos estáticos são acessados pelo nome da classe, não pelo objeto (Vila.NOME_VILA).

    Métodos Estáticos (Métodos de Classe)

    São métodos que não dependem do estado de um objeto (this não pode ser usado). Eles fornecem funcionalidades utilitárias.

    O método main() em Java é o exemplo canônico: ele é estático porque o programa deve começar sem a necessidade de criar um objeto para começar a execução.

    Analogia: Um método utilitário para calcular a área de um círculo ou a dificuldade de um Jutsu, que só precisa de parâmetros de entrada.

    public class JutsuUtil {
      // O método não precisa de um objeto Jutsu para ser executado
      public static String rankJutsu(int nivelChakra) {
          if (nivelChakra > 90) {
              return "Rank S - Lendário";
          }
          return "Rank C - Básico";
      }
    }
    // Chamada: String rank = JutsuUtil.rankJutsu(100); 
    

    🍃Composição vs Herança

    São formas distintas de criar relacionamentos entre classes.

    Herança ("É um")

    Usada quando o relacionamento é de forte tipagem hierárquica. Ex: Chidori é um Ninjutsu.

    Embora promova a reutilização de código, o abuso da herança (criando hierarquias profundas) pode resultar em sistemas rígidos.

    Composição ("Tem um")

    Usada quando o objeto contém outros objetos como atributos. É o relacionamento "Tem um".

    • O Guerreiro (Objeto) tem um Elmo(Objeto).

    A Composição é preferível, pois oferece maior flexibilidade e acoplamento mais fraco.

    Exemplo de Composição: O TimeNinja é composto por membros.

    public class TimeNinja {
      private Ninja lider;          // Composição: Time TEM UM líder
      private List<Ninja> membros;  // Time TEM VÁRIOS membros
    
    
      public TimeNinja(Ninja lider, List<Ninja> membros) {
          this.lider = lider;
          this.membros = new ArrayList<>(); // Inicializa a lista
          this.membros.addAll(membros);
      }
    }
    

    Instanciando a Class TimeNinja:

    // Classe principal para testar
    public class Main {
      public static void main(String[] args) {
          Ninja kakashi = new Ninja("Kakashi Hatake");
          Ninja naruto = new Ninja("Naruto Uzumaki");
          Ninja sasuke = new Ninja("Sasuke Uchiha");
          Ninja sakura = new Ninja("Sakura Haruno");
    
    
          List<Ninja> membrosTime7 = new ArrayList<>();
          membrosTime7.add(naruto);
          membrosTime7.add(sasuke);
          membrosTime7.add(sakura);
    
    
          TimeNinja time7 = new TimeNinja(kakashi, membrosTime7);
          time7.exibirTime();
      }
    }
    

    image

    No relacionamento de Composição/Agregação, é importante definir o ciclo de vida dos objetos. Na Composição estrita, a destruição do objeto pai implica na destruição dos objetos filhos. Na Agregação, o objeto filho pode sobreviver.

    🍥Boas Práticas de Orientação a Objetos em Java

    A POO é mais do que sintaxe; é sobre a **organização** dos componentes.

    • Regra de Ouro do Encapsulamento: Mantenha atributos private e métodos de acesso public. Use setters para implementar regras de validação (ex: garantir que o nome não seja vazio, que o chakra não seja negativo).
    • Sobrecarga vs. Sobrescrita: Lembre-se que Sobrecarga (overloading) diferencia métodos pela assinatura (na mesma classe), enquanto Sobrescrita (overriding) redefine a implementação de um método herdado (em classes filhas).
    • Princípio DRY (Don't Repeat Yourself): Evite repetir código. Use this() em construtores sobrecarregados e utilize a herança para compartilhar código comum entre classes filhas (características básicas de Ninja).
    • Uso Correto de `this` e `super`: this. referencia atributos ou métodos da instância atual. super. chama atributos ou métodos da classe pai ou o construtor da classe pai.
    • Favor Composição sobre Herança: Use a Composição sempre que o relacionamento for "Tem um". Reserve a Herança apenas para o relacionamento claro "É um".
    • Padronização de Nomenclatura: Siga as convenções de Java: CamelCase para nomes de classes e métodos, snake_case (embora não seja o padrão Java para variáveis, ele usa camelCase e UPPER_CASE_SNAKE_CASE para constantes). Classes devem iniciar com letra maiúscula (Ninja), métodos e variáveis com minúscula (getNome).
    • Utilize a Abstração: Use classes abstratas (abstract class) quando definir modelos genéricos que não devem ser instanciados, mas que servem de base para os objetos concretos. Use interfaces para definir capacidades (o que a classe pode fazer, ex: Curandeiro).

    Dominar a Orientação a Objetos é fundamental. Assim como Naruto precisou de prática para dominar o Rasengan e o Modo Sábio, a prática contínua da POO é o único caminho para se tornar um programador de elite em Java.

    📚REFERENCIAS:

    Vídeo: Se não aprender JAVA com esse video. - ̗̀ DESISTE ̖́- -

    LINK

    Documentação JAVA

    LINK

    🔗MINHAS REDES:

    LINKEDIN

    GITHUB

    K.A.I.Z.E.N - significa: "a melhoria contínua."

    Compartilhe
    Recomendados para você
    Cognizant - Mobile Developer
    Luizalabs - Back-end com Python
    PcD Tech Bradesco - Java & QA Developer
    Comentários (2)
    DIO Community
    DIO Community - 21/10/2025 14:42

    Excelente, Arthur! Que artigo épico, inspirador e didático sobre POO com Naruto! É fascinante ver como você aborda os Fundamentos de Java e a Programação Orientada a Objetos (POO) utilizando o universo dos ninjas de Konoha.

    Qual você diria que é o maior desafio para um desenvolvedor ao trabalhar com um projeto que usa o padrão MVC, em termos de manter a separação de responsabilidades e de evitar o acoplamento entre as três camadas, em vez de apenas focar em fazer a aplicação funcionar?

    Arthur Carneiro
    Arthur Carneiro - 21/10/2025 12:04

    Escrevi este artigo com o objetivo de apresentar uma abordagem mais simples e acessível sobre o conceito de Orientação a Objetos. Espero que ele possa ajudar aqueles que estão buscando compreender melhor os fundamentos da programação em Java