A ideia inicial para a criação desse projeto da Agenda é que ela possua alguns aspectos e funcionalidades na qual contenha classes que possam ser desmembradas em diversas atribuições, como por exemplo, na criação de contatos básicos, contatos comerciais, telefone e contatos de email.

Descrição das Classes a serem Utilizadas

Na Figura 1 temos especificado todas as classes do projeto.

Diagrama de classe representando
todas as classes que existirão no projeto, exceto a principal

Figura 1. Diagrama de classe representando todas as classes que existirão no projeto, exceto a principal.

Fique por dentro de tudo que acontece sobre Java na DevMedia e também confira o Checklist Programador Java.

A classe Agenda é responsável por possuir campos e métodos cuja finalidade é buscar os registros e também fazer a inserção.

A classe ContatoBasico contém campos primários a serem herdados e métodos de envio e recebimento de dados.

A classe Contato contém campos para um possível controle residencial ou pessoal do usuário, que por sua vez herda as funcionalidades da classe ContatoBasico e contém o método para obter os dados e a idade.

A classe ContatoComercial contém campos que se destinam para um controle comercial, esta herda as funcionalidades da classe ContatoBasico e contém o método para obter os dados.

A classe Econtato é destinada para o controle mais aprofundado contendo campos de vinculações para o contato como email, por exemplo, também essa classe herda as funcionalidades só que da classe Contato e contém os métodos de obtenção de dados.

Por fim, temos a classe Telefone que contém campos que discriminam o contato telefônico do usuário e contém o método para obtenção dos dados. Essa classe será enunciada apenas na classe Principal (Main) e na classe ContatoBasico.

Iniciando o Projeto

Inicialmente, será criada uma nova aplicação Java, isso após ter aberto o ambiente de desenvolvimento Netbeans. No menu principal, vá em Arquivo e selecione a opção Java -> Aplicação Java, como mostra a Figura 2.

Tela para criação de um Novo
Projeto Java

Figura 2. Tela para criação de um Novo Projeto Java.

Após isso, é só clicar no botão: Próximo. Então aparecerá a seguinte tela, como mostra a Figura 3.

Tela

Figura 3. Tela de configuração para o Nome do Projeto, Localização do Projeto e criação da classe Principal.

Nota: Nesse caso, foi necessário mudar o nome da Classe Principal para Main.

Após ter clicado no botão Finalizar, aparecerá a classe principal Main e com isso já é possível criar as classes adicionais para dentro do projeto. As classes ficarão todas na mesma raiz e terão os seguintes nomes: Agenda.java, Contato.java, ContatoBasico.java, ContatoComercial.java, EContato.java e Telefone.java, que podem ser visualizadas de acordo com a Figura 4.

Layout

Figura 4. Layout das classes criadas e também da classe principal.

Implementando o Projeto

Primeiramente, ao começar o projeto será implementada a classe Telefone.java, como está especificado na Listagem 1.

Listagem 1. Classe Telefone.


  packageappagenda;
  public class Telefone
  {   private String numero;
       private String tipo;
       publicTelefone(String numero, String tipo)
      {   this.numero = numero;
           this.tipo = tipo;
      }
      public String getTelefone()
      {   return numero+" "+tipo;
       }
  } 

Vamos entender o código acima: na classe Telefone são criados dois campos: nome e telefone. Ambos são do tipo String e de visibilidade private. Em seguida é criado o construtor Telefone (String numero, String tipo) que será responsável por apontar a nova criação dos objetos. Finalmente, é criado o método getTelefone() do tipo String que retornará os valores dos dois campos concatenados.

Após ter feito a classe Telefone, será implementado dentro da classe ContatoBasico.java os códigos descritos na Listagem 2.Essa classe contém dados básicos como nome e telefone que possam ser herdados para as outras classes futuramente.

Listagem 2. Classe abstrata referente ao ContatoBasico.


  Package appagenda;
   
  import java.util.ArrayList;
   
  abstract public class ContatoBasico
  {   protected String nome;
      Protected ArrayList<Telefone>telefones;
      public ContatoBasico()
      {  nome="";
         telefones=new ArrayList();
      }
      public ContatoBasico(String nome)
      {  this.nome = nome;
          telefones=new ArrayList();
      }
      public String getNome() { return nome; }
      public void setNome(String nome) { this.nome = nome;}
      public void setTelefone(Telefonetf)
      {  telefones.add(tf);
      }
      public String getDados()
      {   String s=nome+"\n";
           for(Telefone t:telefones)
           {  s+=t.getTelefone()+"\n";
           }
           return s;
      }
  }

Esse código contém uma classe que é abstrata, na qual ela é impedida de ser instanciada, mas dá mais consistência ao sistema e tem a função de servir como herança de atributos e métodos, que serão recursos fundamentais no decorrer do projeto.

Anteriormente, é criado uma importação do ArrayList, que significa uma coleção de vetores armazenados numa Lista.

Logo em seguida são criados os campos nome (do tipo String) e telefones (do tipo ArrayList -isso é uma referência para a classe Telefone) e ambos com visibilidade protected.

Após isso são criados os construtores ContatoBasico() e ContatoBasico(String nome), que vão ser responsáveis por apontarem a nova criação dos objetos.

O método public String getNome() { return nome; } serve para encapsular o campo nome, obtendo seu valor, dentro de uma String e fazer seu retorno.

O método public void setNome(String nome) { this.nome = nome;} é responsávelpor fazer o encapsulamentos do campo nome e também de enviar o seu valor.

O método setTelefone(Telefone tf) é responsável por receber o conteúdo do campo que está contido na classe Telefone e adicionar para o campo telefones.

Por fim, o método getDados() é do tipo String e contém uma String que recebe o nome e o telefone do respectivo contato e faz o retorno dessa variável.

Após ter implementado a classe abstrata ContatoBasico, agora é proposto implementar a classe Contato.java descrita na Listagem 3. Por essa classe fazer parte de uma herança, ela receberá dois dados: nome e data de nascimento.

Listagem 3. Classe Contato que herda da classe ContatoBasico e exibe a data de nascimento de modo formatado e faz cálculos referentes a idade da pessoa.


  Package appagenda;
   
  Import java.util.Calendar;
  Import java.util.GregorianCalendar;
   
  public class Contato extends ContatoBasico
  {
    protected Calendar dtnasc;
    publicContato(String nome, Calendar dtnasc)
      {   super(nome);
           this.dtnasc = dtnasc;
      }
      @Override 
       public String getDados()
       { returnsuper.getDados()+"Nascido em "+
          dtnasc.get(Calendar.DATE)+"/"+
          dtnasc.get(Calendar.MONTH) + "/"+
          dtnasc.get(Calendar.YEAR) + "\nIdade: ";
      }
      public intgetIdade()
      {   Calendar hoje=new GregorianCalendar();
            intidade=hoje.get(Calendar.YEAR)-dtnasc.get(Calendar.YEAR);
            hoje.set(Calendar.YEAR, dtnasc.get(Calendar.YEAR));
            if(hoje.before(dtnasc))
              idade--;
              return idade;
   
      }
  }

Logo no início do código são criadas duas importações: java.util.Calendar e java.util.GregorianCalendar, que fazem referências para as datas e conversões e, com isso, podemos manipular no decorrer da implementação da classe.

Após, é inserido o código extends ContatoBasico, que significa uma herança para a classe ContatoBasico, onde as informações servirão para a classe Contato.

Logo após é criado um campo de data do nascimento (dtnasc) do tipo calendar e de visibilidade protected.

Também é criado o construtor Contato(String nome, Calendar dtnasc) que será responsável por apontar a nova criação dos objetos. Nesse construtor há a propriedade super, na qual faz referência para a variável nome decorrente da classe ContatoBasico.

Como há uma herança, é preciso um método @Override (sobrescrita) que receberá o nome de getDados(), cujo tipo é String e contém um padrão de retorno onde busca os dados da herança (super) concatenando com a data de nascimento, mês e o ano que estão previamentes no registro em memória.

E finalmente, o método getIdade(), do tipo int, é responsável por fazer uma conversão da data em memória em padrões do ano, cuja finalidade é fazer um cálculo para saber a idade do usuário que está presente no registro.

Agora vamos implementar a classe Contato com o nome de Contato Comercial.java, como descrito na Listagem 4. Além dessa classe fazer parte de uma herança, ela receberá dois campos: atividade e funcionário.

Listagem 4. Classe ContatoComercial sendo herdada da classe ContatoBasico e exibe a atividade e o funcionário.


  Package appagenda;
   
  public class ContatoComercial extends ContatoBasico
  {
    protected String atividade;
    protected String funcionario;
   
    publicContatoComercial(String nome, String atividade, String funcionario)
    {   super(nome);
         this.atividade=atividade;
         this.funcionario=funcionario;
    }
    @Override
     public String getDados()
     {  String s=super.getDados();
         s+=atividade+"\n"+" contato Sr(a): "+funcionario;
         return s;
      }
  }

Logo no início do código inserimos extends ContatoBasico, que significa uma herança para a classe ContatoBasico, onde as informações servirão para a classe ContatoComercial.

Logo após são criados dois campos: um com o nome atividade e do tipo String, e outro com o nome funcionário e do tipo String, ambos com visibilidade protected.

Em seguida é criado o construtor ContatoComercial(String nome, String atividade, String funcionario) que será responsável por apontar a nova criação dos objetos. Nesse construtor há a propriedade super, na qual faz referência para a variável nome decorrente da classe ContatoBasico.

E finalmente, como há uma herança, é preciso de um método @Override (sobrescrita), que neste caso receberá o nome de getDados(), cujo tipo é String, e contém um padrão de retorno onde busca os dados da herança (super) concatenando com a atividade e o funcionário que estão previamentes no registro em memória.

Após ter implementado a classe ContatoComercial, agora é proposto implementar a classe EContato.java que está descrita na Listagem 5. Além dessa classe fazer parte de uma herança, ela receberá dois campos: email e homepage.

Listagem 5. Classe EContato sendo herdada da classe Contato e exibe o email e a homepage.


  Package appagenda;
  import java.util.Calendar;
   
  public class EContato extends Contato
  {  protected String email,homepage;
      public EContato(String nome, Calendar dtnasc, String email, String hp)
      {  super(nome,dtnasc);
          this.email=email;
          homepage=hp;
     }
      @Override
      public String getDados() {
        return super.getDados()+"email: "+email+"\nhomepage:"+homepage+"\nIdade: ";
      }
      public String getEmail() {
        return email;
      }
      public String getHomepage() {
         return homepage;
      }
  }

Antes, é criada a importação java.util.Calendar, que faz referência para as datas e conversões. Em seguida é inserido o código extends Contato que significa uma herança para a classe Contato, onde as informações servirão para a classe EContato.

Logo depois são criados dois campos: um com o nome email e outro com o nome homepage, ambos do tipo String e de visibilidade protected.

Após é criado o construtor EContato(String nome, Calendar dtnasc, String email, String hp) que será responsável por apontar a nova criação dos objetos. Nesse construtor há a propriedade super, na qual faz referência para as variáveis nome e dtnasc, decorrentes da classe Contato.

Como há uma herança, é preciso do método @Override (sobrescrita), que neste caso recebe o nome de getDados(), cujo tipo é String, e contém um padrão de retorno onde busca os dados da herança (super) concatenando com o email e a homepage que estão previamentes no registro em memória.

O método getEmail() - que é do tipo String, é responsável por retornar o valor do campo email. E, finalmente, o método getHomepage(), do tipo String, é responsável por retornar o valor do campo homepage.

Na Listagem 6 será implementado os códigos da classe responsável por “moldar” a maioria das funcionalidades do projeto.

Listagem 6. Classe Agenda e suas funcionalidades.


  Package appagenda;
   
  Import java.util.ArrayList;
   
  public class Agenda
  {   private ArrayList<ContatoBasico>contatos;
      Agenda()
      {   contatos=new ArrayList();
      }
      public void inserir(ContatoBasico c)
      {   contatos.add(c);
      }
      Public ContatoBasicobuscar(String nome)
      {   for(int i=0;i<contatos.size();i++)
          {   ContatoBasico c=contatos.get(i);
               if(c.getNome().equalsIgnoreCase(nome))
                 return contatos.get(i);
          }
          return null;
      }
      Public ContatoBasicobuscar(intpos)
      {   if(pos>=0 &&pos<contatos.size())
          {   returncontatos.get(pos);
          }
          return null;
      }
      Public EContatobuscarEmail(String email)
      {   for(int i=0;i<contatos.size();i++)
          {   if(contatos.get(i) instanceofEContato)
              {
                EContato c=(EContato)contatos.get(i);
                if(c.getEmail().equalsIgnoreCase(email))
                return (EContato)contatos.get(i);
              }
          }
          return null;
      }
      Public Contato[] buscarGeral(String palavraChave)
      {   ArrayList<ContatoBasico>todos=new ArrayList();
           for(int i=0;i<contatos.size();i++)
            {   ContatoBasico c=contatos.get(i);
                 if(c.getDados().contains(palavraChave))
                   todos.add(c);
             }
             Contato[] vet=new Contato[todos.size()];
   
              return (todos.toArray(vet));
       }
       Public Contato[] buscarTodos()
      {   Contato[] vet=new Contato[contatos.size()];
   
           return (contatos.toArray(vet));
      }
      Public intgetQuantidade()
     {  returncontatos.size();
      }    
  }

Essa classe Agenda é considerada uma das classes que mais operam no projeto, pois contém métodos que servem para fazer consultas via registros que foram previamente colocados na memória, buscar a quantidade de contatos e também fazer a inserção de registros.

Anteriormente, é criado uma importação do ArrayList (que significa uma coleção de vetores armazenados numa Lista).

Logo em seguida é criado o campo contatos do tipo ArrayList< ContatoBasico> (isso é uma referência para a classe ContatoBasico) e com visibilidade protected.

Após é criado o construtor Agenda() que contém a declaração inicial do recebimento do ArrayList para a variável contatos.

O método inserir(ContatoBasico c) é responsável por controlar toda a inserção de dados para a memória, sempre de acordo com o parâmetro nome vindo da classe abstrata ContatoBasico.

O método buscar(String nome), do tipo ContatoBasico, é responsável por realizar uma busca de todos os dados nos quais se referem ao registro do ContatoBasico através do nome informado.

O método buscar(intpos), do tipo ContatoBasico,é quem faz uma busca de todos os dados nos quais se referem ao registro do ContatoBasico através da posição informada.

O método buscarEmail(String email), do tipo Econtato, é responsável por buscar os dados do registro referentes a pesquisa feita por email do contato.

O método buscarGeral(String palavraChave), do tipo Contato[] (vetorizado), é responsável por fazer uma busca de todos os registros do contato de acordo com os caracteres inseridos para a pesquisa. Neste caso, não há distinção para a busca, sendo tanto o Contato quanto ContatoBasico.

O método buscarTodos(), do tipo Contato[] (vetorizado), é quem faz a busca de todos os registros, sem que o usuário afirme algum valor sequer para a pesquisa.

O método intgetQuantidade() é responsável por retornar a quantidades de registros existentes na memória.

Agora vamos escrever a nossa classe principal, a classe Main, que é implementada de acordo com a Listagem 7.

Listagem 7. Classe Principal do Projeto, onde se localizam o controle de dados para o usuário e a ocorrência de eventos.


  Package appagenda;
   
  Import java.util.GregorianCalendar;
   
  public class Main
  {   static void mostraDados(ContatoBasicoobj)
      {  System.out.println(obj.getDados());
          if(objinstanceofContato)
            System.out.println(((Contato)obj).getIdade());
            System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxx");
      } 
       public static void main(String[] args) 
       {   Agenda a;
            a=new Agenda();
   
            Contato cb;
             cb=new Contato("Teste",newGregorianCalendar(1980,10,28));
             cb.setTelefone(new Telefone("3333-5555","Telefone residencial"));
             cb.setTelefone(new Telefone("99111-1111","Telefone celular"));
             a.inserir(cb);
   
             ContatoComercial cc;
             cc=new ContatoComercial("Lanchonete", "Lanches", "Lan");
             cc.setTelefone(new Telefone("2222-0000","Telefone residencial"));
             a.inserir(cc);
   
            a.inserir(new EContato("Exemplo",newGregorianCalendar(1975,2,22),
                  "exemplo@gmail.com","www.exemplo.com.br"));
   
            ContatoBasicoobj=a.buscar("Teste"); //pesquisa por nome
   
            if(obj!=null)
              mostraDados(obj);
              elseSystem.out.println("Contato nao encontrado!");
           }
  }

O primeiro passo é a importação java.util.GregorianCalendar; que faz referência para as datas e conversões.

O método mostraDados(ContatoBasicoobj) recebe os dados da classe ContatoBasico e envia para o objeto objconvertendo os dados para o tipo Contato e concatenando com a idade.

Finalmente, o método principal do projeto - main(String[] args) - é responsável por receber as classes Agenda, Contato (que insere na memória um novo contato contendo: nome, data, telefone residencial, telefone celular), ContatoComercial (que insere na memória um novo contato comercial contendo: nome, telefone residencial), EContato (que insere na memória um novo email para contato e um ano de acordo com o nome) e a classe ContatoBasico é instanciada recebendo o valor da pesquisa e o tipo da pesquisa, onde no exemplo é a pesquisa por nome.

Se o objeto obj for diferente de null, quer dizer que retornou resultados, mostrando dados do objeto no console System.out.println, senão, é impresso uma mensagem simples dizendo que o contato não foi encontrado.

Podemos ver a execução do projeto na Figura 5.

Tela de exibição do resultado em
console

Figura 5. Tela de exibição do resultado em console onde contém os dados do contato de nome: “Teste”, telefone residencial, telefone celular, data de nascimento e idade.