Entendendo Herança em Java com um Projeto Prático de Clube de Fitness

Herança em Java: Um Estudo Prático com Clube de Fitness

Caros alunos e alunas, hoje vamos desvendar um dos pilares da Programação Orientada a Objetos (POO) em Java: o conceito de herança. Para solidificar nosso aprendizado, mergulharemos em um projeto prático — um sistema de gestão para um clube de fitness. Este clube oferece diferentes tipos de associação, VIP e Normal, e queremos modelar essa realidade em nosso código. Preparados? Vamos iniciar!

Configurando o Ambiente no NetBeans com Maven

Primeiramente, é imprescindível configurar nosso ambiente de desenvolvimento. Estaremos utilizando o NetBeans com Maven, uma escolha excelente para gerenciar nossos projetos Java e suas dependências.

  1. Abra o NetBeans.
  2. Vá em File > New Project.
  3. Selecione Java with Maven.
  4. Escolha Project from Archetype e selecione o archetype maven-archetype-quickstart.
  5. Nomeie o projeto como InheritanceDemo.
  6. Certifique-se de que o GroupId é com.mycompany e o ArtifactId é inheritancedemo.

Com esses passos, teremos nosso projeto pronto para começarmos a programar.

Entendendo a Classe Base: Member.java

No coração do nosso sistema, reside a classe Member. Ela representa um membro genérico do nosso clube de fitness e contém informações e comportamentos comuns a todos os membros. Vamos dissecar essa classe:

Aqui, declarou-se a classe Member no pacote com.mycompany.inheritancedemo. Note que há uma importação da classe Scanner do pacote java.util, pois manipularemos a entrada do usuário.

No corpo da classe Member, definimos campos que armazenam informações sobre o membro e métodos que determinarão o comportamento do membro.

Construtores

Possuímos dois construtores: um sem parâmetros e outro que recebe nome, ID e o ano de filiação como parâmetros. O construtor é uma “função especial” que é chamada quando um objeto é instanciado.

Métodos

Os métodos getDiscount e setDiscount são exemplos de métodos de acesso, também conhecidos como getters e setters. Eles servem para ler e modificar campos privados, mantendo o encapsulamento.

Derivando Classes Especiais: VipMember e NormalMember

Em nosso projeto, temos dois tipos específicos de membros que herdam características da classe Member. Isso é onde a herança brilha, permitindo-nos estender e especializar a classe base.

VipMember.java

A palavra-chave extends é usada para declarar que VIPMember é uma subclasse de Member. Assim, VIPMember herda todos os campos e métodos de Member.

Observem o uso da anotação @Override. Ela sinaliza que o método calculateAnnualFee está sendo sobrescrito, ou seja, VIPMember fornece sua própria implementação deste método.

NormalMember.java

A classe NormalMember segue uma estrutura semelhante à VIPMember, também sobrescrevendo o método calculateAnnualFee. A diferença reside na forma como a taxa anual é calculada.

Integrando as Peças: InheritanceDemo.java

A classe InheritanceDemo com o método main é o ponto de entrada do nosso programa. Quando executamos o aplicativo, é esse método que o Java chama.

Aqui, instanciamos objetos das classes VIPMember e NormalMember, invocamos métodos para calcular suas taxas anuais e exibir suas informações.

 

Vamos decifrar a classe Member. Essa classe é a base do nosso sistema e retrata os membros genéricos de um clube de fitness. Todos os membros, independente do tipo, terão as características comuns definidas nesta classe.

Essa é a estrutura básica da nossa classe Member. Ela está dentro do pacote com.mycompany.inheritancedemo e importa a classe Scanner do pacote java.util para capturar a entrada do usuário.

Declaração de Variáveis

Aqui temos seis campos (variáveis) que armazenam informações sobre um membro genérico do clube de fitness. Cada um desses campos tem diferentes níveis de acesso:

  • public: Este campo pode ser acessado de qualquer lugar do nosso código. Ele é usado para a mensagem de boas-vindas, que é comum a todos os membros.
  • protected: Este campo pode ser acessado dentro da mesma classe, em qualquer classe que herde dessa classe e em qualquer classe no mesmo pacote. Usamos protected para annualFee porque queremos que as subclasses (VIP e Normal) possam acessar e modificar este valor.
  • private: Estes campos só podem ser acessados dentro da mesma classe. Utilizamos private para os detalhes específicos do membro como name, memberID, memberSince e discount para encapsular essas informações e protegê-las de alterações indesejadas.

Construtores

Os construtores são métodos especiais em uma classe que são chamados quando um objeto dessa classe é criado. Eles têm o mesmo nome da classe e não têm tipo de retorno. Nossa classe Member possui dois construtores:

  • O primeiro é um construtor sem parâmetros, que imprime uma mensagem no console. Este construtor será chamado quando criamos um membro sem fornecer nenhum detalhe específico.
  • O segundo construtor aceita três parâmetros e atribui esses valores aos campos correspondentes da classe. Este construtor será chamado quando quisermos criar um membro fornecendo seu nome, ID e ano de inscrição. O termo this é usado para se referir ao objeto atual, diferenciando os campos da classe dos parâmetros do construtor.

Métodos Getter e Setter

O método getDiscount() é um getter que retorna o valor do campo discount.

O método setDiscount() é um setter que modifica o valor do campo discount. Aqui, pedimos ao usuário que insira uma senha de administrador para verificar se eles têm a permissão necessária para alterar o desconto. Se a senha for correta, pedimos que insiram o novo valor de desconto e atualizamos o campo discount com esse valor.

Métodos Comportamentais

O método displayMemInfo() é responsável por imprimir as informações do membro no console

Aqui está o código Completo da Classe Member

A Classe VipMember

Agora que já compreendemos a classe base Member, vamos explorar uma de suas subclasses, a VipMember. Lembrando, a classe VipMember representa um membro VIP do clube de fitness, que possui algumas características e comportamentos específicos.

Observe a declaração da classe. A palavra-chave extends é usada para indicar que VipMember é uma subclasse de Member. Isso significa que VipMember herda todos os campos e métodos da classe Member, permitindo também adicionar ou sobrescrever funcionalidades.

Construtor

Aqui temos o construtor de VipMember, que recebe três parâmetros: nome, ID do membro e o ano de filiação. Dentro do construtor, vemos uma chamada para super(pName, pMemberID, pMemberSince). A palavra-chave super é usada para invocar o construtor da superclasse Member. Ou seja, quando um novo VipMember é criado, este construtor chama o construtor da classe Member que corresponde aos parâmetros fornecidos, o que garante que esses campos sejam devidamente inicializados.

Método Sobrescrito

Este é um exemplo de sobrescrita de métodos. A anotação @Override indica que estamos fornecendo uma nova implementação para o método calculateAnnualFee que já existe na superclasse Member.

O cálculo da taxa anual para um membro VIP é diferente do membro genérico. A taxa é inicialmente definida como 1200 e, em seguida, um desconto é aplicado. O método getDiscount(), que é herdado da superclasse Member, é usado para obter o valor do desconto.

Portanto, embora VipMember seja uma subclasse de Member e herde seus campos e métodos, ele pode personalizar seu comportamento sobrescrevendo métodos conforme necessário. Isso é uma demonstração do poder da herança: permite-nos reutilizar código, mas ainda assim personalizar onde precisamos. É assim que conseguimos modelar uma variedade de membros com características e comportamentos únicos, mas mantendo um design de código elegante e sustentável.

Aqui está o código completo da Classe VipMember

A Classe NormalMember

Agora vamos para a classe NormalMember. Assim como a VIPMember, ela também é uma subclasse de Member e representa um membro normal no clube de fitness. Embora um membro normal compartilhe muitas características com um membro VIP, ele também possui suas próprias particularidades.

A palavra-chave extends é utilizada para indicar que NormalMember é uma subclasse de Member. Portanto, NormalMember herda todos os campos e métodos de Member, mas também permite adicionar ou sobrescrever características e comportamentos próprios dos membros normais.

Construtor

O construtor de NormalMember aceita três parâmetros: nome, ID de membro e o ano de filiação. Usamos a palavra-chave super para invocar o construtor da superclasse Member com esses parâmetros. Esta chamada ao construtor pai garante que esses campos sejam devidamente inicializados na criação de um novo NormalMember.

Método Sobrescrito

Este é outro exemplo da sobrescrita de métodos. A anotação @Override sinaliza que estamos fornecendo uma implementação específica para o método calculateAnnualFee que foi herdado da classe Member.

O cálculo da taxa anual para um membro normal é diferente daquela de um membro genérico ou VIP. O método getDiscount(), herdado de Member, é usado para obter o valor de desconto. A taxa é definida como 100 acrescida de 100 multiplicado pelo desconto em porcentagem.

Neste ponto, pode-se observar como a herança possibilita a criação de subclasses distintas a partir de uma classe base. Embora NormalMember e VIPMember herdem muitas características de Member, cada um fornece uma implementação única do método calculateAnnualFee, que reflete as diferenças entre os dois tipos de membros. Com isso, conseguimos representar tanto membros VIP quanto normais de maneira eficaz, preservando as semelhanças e respeitando as diferenças.

Aqui está o Código Completo da Classe NormalMember:

A Classe InheritanceDemo e Implementação do Método main()

O método main() em uma aplicação Java é o ponto de entrada do programa. É onde a execução começa quando você executa a classe contendo o método. Em nosso programa de clube de fitness, o método main() será responsável por instanciar objetos de membros do clube, calcular suas taxas anuais e exibir suas informações.

Vamos detalhar a implementação do método main() do nosso programa InheritanceDemo:

Instanciando Membros

Neste trecho, criamos dois objetos: um para VIPMember e outro para NormalMember. O construtor de cada classe é chamado e recebe três parâmetros: o nome do membro, o ID do membro e o ano desde que ele se tornou um membro. Essas informações são passadas para a superclasse Member através da palavra-chave super, que invoca o construtor correspondente na classe Member.

Calculando a Taxa Anual

Depois de instanciar os objetos dos membros, chamamos o método calculateAnnualFee() de cada um. Este método é uma versão sobrescrita do método presente na classe base Member. Para VIPMember, este método calcula a taxa anual com um determinado desconto, enquanto para NormalMember, ele calcula a taxa anual de uma maneira potencialmente diferente (conforme a implementação de calculateAnnualFee() para essa subclasse).

Exibindo Informações dos Membros

Agora que as taxas anuais foram calculadas, exibimos as informações de cada membro chamando o método displayMemInfo(). Este método imprime detalhes do membro, como o nome, ID do membro, o ano desde que se tornaram membros e a taxa anual. Como este método não foi sobrescrito nas subclasses, o método da superclasse Member é utilizado aqui.

Resumo do Método main()

Em resumo, o método main() do nosso programa faz o seguinte:

  1. Cria objetos para diferentes tipos de membros.
  2. Calcula as taxas anuais de acordo com o tipo de membro.
  3. Exibe as informações dos membros.

Através da herança, fomos capazes de estabelecer uma relação entre membros VIP e Normais com a classe Member, reutilizando código e comportamento. O método main() demonstra o uso prático dessas classes e métodos numa aplicação Java simples.

Aqui está a implementação completa do método main() na classe InheritanceDemo:

Cada linha do código no main() executa uma ação específica e juntas formam um fluxo lógico que define a execução do nosso programa. Ao compreender o papel de cada linha no método main(), você está um passo mais perto de dominar a lógica de programação em Java.

Conclusão: O Poder da Herança

O projeto que acabamos de construir ilustra a elegância e a eficiência da herança. As classes VipMember e NormalMember reutilizam a estrutura da classe Member, cada uma adicionando suas especificidades.

Por meio deste exemplo prático, espero que tenham captado a essência da herança em Java. Ela facilita a expansão e a manutenção de nossos programas ao permitir o compartilhamento de código comum e a criação de uma hierarquia clara de classes. Continuem praticando e explorando, pois cada linha de código escrita fortalece sua compreensão da POO em Java. Lembrem-se, a prática leva à perfeição!

Scroll to Top