Mostrando postagens com marcador Java. Mostrar todas as postagens
Mostrando postagens com marcador Java. Mostrar todas as postagens

segunda-feira, 17 de agosto de 2015

Novidade!!! Agora vamos ter canal no Youtube =D

Fala pessoal tudo beleza, estou sumido a correria está forte por aqui. Estou querendo dar um start em um projeto antigo que vem desde o tempo da Faculdade que é fornecer um site onde as pessoas possam aprender um pouco de programação Python e Java comigo =D.

Não sou nenhum guru mas tenho algumas experiências que gostaria de compartilhar, e para começar fiz uma vídeo aula piloto onde todos podem deixar comentários com criticas para melhorar essa bagaça. Clique aqui para assistir.

Pessoal é 100% gratuito e não pretendo cobrar nada hein ... Valeu amigos =D

quarta-feira, 22 de janeiro de 2014

Iterator - java.util.Iterator (Post relâmpago)

Fala pessoal, hoje vou falar brevemente da Interface Iterator da nossa querida linguagem de programação Java. Será um post muito prático e sem muito explicação da Interface em si.

Iteradores

Geralmente usamos Lists em nosso código Java, usamos o nosso querido foreach para varrer as informações e pronto, mas algumas vezes temos que ler os itens contidos na List sem estar em uma estrutura de repetição. Quando temos esse tipo de problema a solução mais correta em Java é contar com o auxilio de Iterator que nada mais é que uma Interface.

Essa interface Java disponibiliza alguns métodos muitos úteis e que vão ajudar a você percorrer os elementos um a um sem ter que contar com uma estrutura de repetição. Além de percorrer um a um, o Iterator consegue dizer se ainda há elementos a serem lidos possibilitando assim uma construção em bloco de condição. E por fim uma ultima vantagem e a mais incrível do Iterator é poder modificar o número de elementos enquanto ele é varrido em uma construção while.

Hora do código

Haha, agora é a hora que eu paro de falar e começo a programar =p.

Observe e veja, nesse código utilizamos todos os métodos da Interface Iterator: hasNext(), next() e remove(). Segue o código:


terça-feira, 16 de abril de 2013

Erros comuns que acontecem com iReport




Olá pessoal, hoje vou falar de uma experiência desagradável que tive na minha vida. Vou falar do polêmico iReport. 

O iReport é uma ferramenta para construção de relatórios em vários formatos, tais como: HTML, XLS e PDF. O iReport pode ser utilizado com a linguagem de programação Java ou PHP.

Sem dúvidas o iRepot é uma excelente ferramenta no que se diz respeito à criação de relatórios, porém, seu uso pode acarretar uma experiência não muito agradável. Recentemente utilizei o iReport em um projeto onde tive que criar desde relatórios simples a relatórios mais elaborados. Tive vários probleminhas que tive que descobrir com ajuda de alguns gurus Java e outros que tive que descobrir na raça mesmo.

Por esse motivo fiz um compilado dos problemas que tive na hora de gerar meus relatórios.

  1. Versões diferentes
  2. Fontes diferentes
  3. Gerar .jar 

Versões diferentes

O iReport possui várias versões e nenhuma delas são compatíveis entre si. Se você construir um relatório utilizando a versão 3 e no seu projeto você está utilizando a biblioteca da versão 4 o relatório não irá rodar. O que é no minimo estranho já que sua biblioteca é de uma versão superior a do seu relatório. 

Mas o maior problema não é quando o relatório não roda, o problema começa quando você debuga para achar o erro. Quando você debuga o seu projeto o mesmo diz que não tem nenhum erro e passa normalmente o código, deixando o programador muito confuso já que erros não foram detectados e mesmo assim o seu relatório não abre.

Então se você está desenvolvendo aplicações com iReport e seu relatório não está abrindo fique atento provavelmente a versão do iReport que você incluiu no diretório libs de seu projeto não é a mesma versão do iReport em que o arquivo foi desenhado. 

Fontes diferentes

Parece brincadeira de mal gosto mas é isso mesmo, se seu relatório contem fontes que não estejam instaladas no sistema operacional do cliente ele se quer irá abrir ou muito menos dar uma mensagem de erro. Isso acontece também pelo fato do iReport ser na minha opinião um pouco "ingenuo", ora se a fonte não está instalada no cliente apresente uma fonte padrão da mesma família da fonte não instalada, por exemplo: sans-serif, serif, courier, etc.

Uma dica de quem já quebrou a cabeça com isso. Use somente fontes que você tenha certeza que estejam instaladas no cliente, ou use fontes que sejam genéricas como: sans-serif, serif, etc.

Gerar .jar

Esse é um problema muito frequente em qualquer tipo de aplicação, mas quando você utiliza o iReport ele pode ficar um pouco mais chatinho de resolver. O jar é o executável de um programa Java então todos os arquivos de seu programa estão contidos no jar. Caso você não inclua os arquivos em seu .jar o mesmo não irá executar na máquina cliente ... mesmo se você instalar o iReport na máquina do cliente.

Parece coisa de boçal essa dica mas programadores .NET irão gostar,  pois o Crystal Reports você não libera ele com a aplicação você deve instalá-lo na máquina do cliente.

Bom pessoal por hoje é só e nos vemos no próximo post. Bons estudos!!!

terça-feira, 9 de abril de 2013

Trabalhando com vários arquivos *.java

Fala pessoal, hoje vou mostrar como trabalhar com mais de um arquivo (.java) em seus projetos.

Introdução

Quando estamos aprendendo a programar geralmente escrevemos nossos códigos em um único arquivo. Isso é feito para que o aluno não se perca no decorrer de seu aprendizado e trabalhar com um único arquivo é muito mais simples do que trabalhar com vários.
Quando estamos programando no paradigma orientado a objetos muitas vezes (senão sempre) precisamos de mais que um arquivo. Programas grandes costumam possuir vários arquivos onde uma parte do código chama outro parte de código de um arquivo diferente.
Bom visto que para grandes programas temos que usar mais de um arquivo vamos então aprender como programar utilizando mais de um arquivo ... bora lá pé de pano?

Brincando com os arquivos

Vamos imaginar que temos o seguinte problema: Precisamos desenvolver um sistema para uma loja de jóias, essa loja deseja realizar o cadastro de produtos e clientes. Vamos deixar só isso por enquanto pequeno gafanhoto depois retomamos e brincamos mais ;-)

De acordo com o texto acima eu sei que vou ter no mínimo 3 arquivos não é mesmo? O primeiro arquivo seria para escrever código de manipulação de clientes, o segundo de produtos e o terceiro arquivo seria a minha classe principal.

Mais a questão é: "E se eu quiser fazer tudo no mesmo arquivo?". Na tem problema algum em codificar um programa inteiro em um único arquivo, vejamos por exemplo como criar as 3 classes de nosso programa em um único arquivo:


public class TestJoalheria { public static void main() { // CÓDIGO OCULTO } } public class Cliente { // CÓDIGO OCULTO } public class Produto { // CÓDIGO OCULTO }
Esse seria o nosso arquivo único com todas as classes que nosso sistema possui. Veja que não tem problema algum em ter todo o código em um único arquivo. A desvantagem em ter tudo programado em apenas um único arquivo seria a complexidade que o código ganharia. Imagine ter que procurar um erro em um arquivo que tenha 50 classes e o total de linhas seja igual à 100.000 linhas?!

Já que tratar tudo em um arquivo é algo muito complexo, imagine agora se o mesmo programa de 100.000 linhas estivesse divido em 50 arquivos diferentes. É muito mais fácil procurar um erro em um arquivo que você sabe que o erro está ali e esse arquivo tem agora 2000 linhas ... conseguiu enxergar a vantagem pequeno gafanhoto?

Bom vamos ver como ficou o código da Joalheria em vários arquivos? DICA: INCREMENTE FUNCIONALIDADES A MAIS NO SOFTWARE, SEI LÁ CONSTRUA UMA INTERFACE GRÁFICA ... OU DEIXE UM COMENTÁRIO DIZENDO O QUE GOSTARIA QUE EU MODIFICASSE NO CÓDIGO PARA TE AJUDAR MELHOR. BONS ESTUDOS. 

Cliente.java
public class Cliente { private String nome; private int idade; private String endereco; private String telefone; public Cliente(String nome, int idade, String endereco, String telefone) { this.nome = nome; this.idade = idade; this.endereco = endereco; this.telefone = telefone; } public String getNome() { return nome; } public int getIdade() { return idade; } public String getEndereco() { return endereco; } public String getTelefone() { return telefone; } }

Produto.java public class Produto { private String descricao; private float preco; private int estoque; public Produto(String descricao, float preco, int estoque) { this.descricao = descricao; this.preco = preco; this.estoque = estoque; } public String getDescricao() { return descricao; } public float getPreco() { return preco; } public int getEstoque() { return estoque; } }

Joalheria.java import java.util.List; import java.util.ArrayList; public class Joalheria { private List clientesCadastrados; private List produtosCadastrados; public Joalheria() { clientesCadastrados = new ArrayList<>(); produtosCadastrados = new ArrayList<>(); } public boolean adicionarCliente(Cliente cliente) { if (cliente != null) { clientesCadastrados.add(cliente); return true; } return false; } public boolean adicionarProduto(Produto produto) { if (produto != null) { produtosCadastrados.add(produto); return true; } return false; } public List getClientesCadastrados() { return clientesCadastrados; } public List getProdutosCadastrados() { return produtosCadastrados; } public int qtdeClientesCadastrados() { return clientesCadastrados.size(); } public int qtdeProdutosCadastrados() { return produtosCadastrados.size(); } }

TestJoalheria.java import javax.swing.JOptionPane; public class TestaJoalheria { Joalheria joalheria = new Joalheria(); private boolean cadastrarCliente(String nome, int idade, String endereco, String telefone) { return joalheria.adicionarCliente(new Cliente(nome, idade, endereco, telefone)); } private boolean cadastrarProduto(String descricao, float preco, int estoque) { return joalheria.adicionarProduto(new Produto(descricao, preco, estoque)); } private void imprimirClientes() { int qtde = joalheria.qtdeClientesCadastrados(); if (qtde > 0) { System.err.println("Número de clientes cadastrados na base de dados: " + qtde); for (Cliente c : joalheria.getClientesCadastrados()) { System.out.println("Nome: " + c.getNome()); System.out.println("Idade: " + c.getIdade()); System.out.println("Endereço: " + c.getEndereco()); System.out.println("Telefone: " + c.getTelefone()); System.out.println("------------------------------------"); } } else { System.err.println("Nenhum cliente encontrado!"); } } private void imprimirProdutos() { int qtde = joalheria.qtdeProdutosCadastrados(); if (qtde > 0) { System.err.println("Número de produtos cadastrados na base de dados: " + qtde); for (Produto p : joalheria.getProdutosCadastrados()) { System.out.println("Descrição: " + p.getDescricao()); System.out.println("Preço: " + p.getPreco()); System.out.println("Estoque: " + p.getEstoque()); System.out.println("------------------------------------"); } } else { System.err.println("Nenhum produto encontrado!"); } } // Esse cara nada mais é que o método que dá o ponta pé inicial public static void main(String[] args) { int opcao; TestaJoalheria test = new TestaJoalheria(); do { opcao = Integer.parseInt(JOptionPane.showInputDialog("Informe o que deseja cadastrar: \n1-Produtos\n2-Clientes\n\n0-Sair")); if (opcao == 1) { String descricao = JOptionPane.showInputDialog("Entre com a descrição do produto"); float preco = Float.parseFloat(JOptionPane.showInputDialog("Entre com o preço")); int estoque = Integer.parseInt(JOptionPane.showInputDialog("Entre com a quantidade em estoque")); if (!test.cadastrarProduto(descricao, preco, estoque)) { JOptionPane.showMessageDialog(null, "Erro ao cadastrar produto!"); } else { JOptionPane.showMessageDialog(null, "Produto cadasrtrado com sucesso!"); } } else if (opcao == 2) { String nome = JOptionPane.showInputDialog("Entre com o nome"); int idade = Integer.parseInt(JOptionPane.showInputDialog("Entre com a idade")); String endereco = JOptionPane.showInputDialog("Entre com o endereço"); String telefone = JOptionPane.showInputDialog("Entre com o telefone"); if (!test.cadastrarCliente(nome, idade, endereco, telefone)) { JOptionPane.showMessageDialog(null, "Erro ao cadastrar cliente!"); } else { JOptionPane.showMessageDialog(null, "Cliente cadasrtrado com sucesso!"); } } else { JOptionPane.showMessageDialog(null, "Sistema finalizado!!!"); } } while(opcao != 0); test.imprimirProdutos(); test.imprimirClientes(); } }

terça-feira, 19 de março de 2013

MinhaString & MinhaData

Fala pessoal, se você acompanha o blog e quando lê esses posts que não explicam absolutamente nada e que apenas possuem códigos e enunciados saiba que eles fazem parte das listas de exercícios da faculdade que eu curso (Instituto Federal de Educação, Ciência e Tecnologia de São Paulo - campus Araraquara). Bom hoje vou postar mais um  desses exercícios, porém, leia o código copie e execute ai na sua máquina, aproveite para brincar e descobrir o que ele faz ... isso te dará um conhecimento extra que muitas vezes deixamos escapar em uma explicação mais formal. Beleza?!

Enunciados:


A classe MinhaData está muito simples, implemente as seguintes melhorias:
  • Não permitir que uma data inválida seja instanciada. Caso tente-se instanciar uma data inválida instancie 01/01/1900.
  • Implemente um construtor que aceite várias ordens de argumentos parainstanciar uma data. Por exemplo, o mesmo construtor deve receber osseguintes dados: (1, 2, 1900) ou (1900, 2, 1) e instanciar a data 01/02/1900.
  • Implementar um método que retorne a data por extenso.
  • Implementar um método que retorne a quantidade de dias entre a data instanciada e uma data passada como argumento.
A classe MinhaString:
  • Sabe-se que em Java ou mesmo em C não existe um tipo primitivo para armazenar uma String. Implemente a classe MinhaString que permita manipular um conjunto de até 256 caracteres. Implemente todas as funcionalidades que acharem interessante para esta classe, como por exemplo: converter para maiúsculo, inverter o texto, comparar dois textos.

MinhaData.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logica;

/**
 *
 * @author guilherme
 */
public class MinhaData {
    private int dia;
    private int mes;
    private int ano;

    public MinhaData(int param1, int param2, int param3, String mascara) {
        organizaValores(mascara, param1, param2, param3);
    }

    private void confereData(int dia, int mes, int ano) {
        boolean dataValida = true;
     
         /* Verifica ano */
        if(ano < 0) {
            dataValida = false;
        } else {
            this.ano = ano;
        }
     
        if(mes < 0 || mes > 12) {
            dataValida = false;
        } else {
            this.mes = mes;
        }
     
        /* Verifica se o dia é válido */
        if(dia > 1 && dia < 31) { //verifica se o dia não é negaivo
            if(mes == 2) {
                if(dia < 28 || (dia == 29 && anoBissexto(this.ano))) {
                    this.dia = dia;
                } else {
                    dataValida = false;
                }
            } else if(mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8
                    || mes == 10 || mes == 12) {
                    this.dia = dia;
            } else {
                if(dia > 30) {
                    dataValida = false;
                }
                this.dia = dia;
            }
        } else {
            dataValida = false;
        }
     
        /* Se a data não for válida então aplica-se a data padrão */
        if(!dataValida) {
            this.dia = 1;
            this.mes = 1;
            this.ano = 1990;
        }
     
    }
 
    private boolean anoBissexto(int ano) {
        if(ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0)) {
            return true;
        }
        return false;
    }
 
    public String imprimeData(String padrao) {
        switch(padrao.toLowerCase()) {
            case "pt-br":
                return dia + "/" + mes + "/" + ano;
            case "us":
                return ano + "-" + mes + "-" + dia;
            default:
                return null;
        }
    }

    private void organizaValores(String mascara, int param1, int param2, int param3) {
        switch(mascara) {
            case "ymd":
                confereData(param3, param2, param1);
                break;
            case "ydm":
                confereData(param3, param1, param2);
                break;
            case "myd":
                confereData(param2, param3, param1);
                break;
            case "mdy":
                confereData(param2, param1, param3);
                break;
            case "dmy":
                confereData(param1, param2, param3);
                break;
            case "dym":
                confereData(param1, param3, param2);
                break;
            default:
                confereData(0, 0, 0);
                System.out.println("Esse formato não existe!");
        }
    }

    public String dataPorExtenso() {
        String[] meses = {"janeiro", "fevereiro", "março", "abril", "maio", "junho"
        ,"julho", "agosto", "setembro", "outubro", "novembro", "dezembro"};
     
        return String.valueOf(dia) + " de " + meses[mes - 1] + " de " + String.valueOf(ano);
    }
 
    public double qtdeDeDias(MinhaData data1, MinhaData data2) {
     
        int[] nroDiasMes = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int dias = 0;
 
        for(int i=0; i<data1.ano; i++) {
            if(anoBissexto(i)) {
                dias += 366;
            } else {
                dias += 365;
            }
        }
     
        for(int i=0; i<data1.mes; i++) {
            dias += nroDiasMes[i];
        }
     
        for(int i=0; i<data1.dia; i++) {
            dias += 1;
        }
     
        for(int i=0; i<data2.ano; i++) {
            if(anoBissexto(i)) {
                dias -= 366;
            } else {
                dias -= 365;
            }
        }
     
        for(int i=0; i<data2.mes; i++) {
            dias -= nroDiasMes[i];
        }
     
        for(int i=0; i<data2.dia; i++) {
            dias -= 1;
        }
     
     
        return Math.abs(dias);
    }

}


MinhaString.java
package logica;

/**
 *
 * @author guilherme
 */
public class MinhaString {
    char[] str;

    public MinhaString(char[] str) {
        this.str = str;
    }
   
    public int tamanho(char[] str) {
        int tamanho = 0;
        for(char c : str) {
            ++tamanho;
        }
        return tamanho;
    }
 
    public char[] concatena(char[] str) {
        int tam = tamanho(str) + tamanho(this.str);
        char[] aux = new char[tam];
     
        for(int i = 0; i < tamanho(this.str); i++) {
            aux[i] = this.str[i];
        }
     
        for(int i = tamanho(this.str), j = 0; i < tam; i++, j++) {
            aux[i] = str[j];
        }
     
        this.str = aux;
     
        return this.str;
    }
 
    public char[] maiuscula() {
        char[] aux = str;
        for(int i=0; i < tamanho(aux); i++) {
            if(str[i] > 96 && str[i] < 123) {
                str[i] -=32;
            }
        }
        return this.str;
    }
 
    public char[] minuscula() {
        char[] aux = str;
        for(int i=0; i < tamanho(aux); i++) {
            if(str[i] > 64 && str[i] < 91) {
                str[i] +=32;
            }
        }
        return this.str;
    }
 
    public char[] inverte() {
        int tam = tamanho(str);
        char[] x = espelha(str);
        for(int i=tam-1, j=0; i > -1; i--, j++) {
            str[j] = x[i];
        }
        return this.str;
    }
 
    public char[] trocarCaracter(char caracterAntigo, char caracterNovo) {
        char[] aux = espelha(str);
        for(int i=0; i<tamanho(aux); i++) {
            if(str[i] == caracterAntigo) {
                str[i] = caracterNovo;
            }
        }
        return str;
    }
 
    public char[] subString(int x, int y) {
        int tam = tamanho(str);
        if( (x >= 0 && x <= tam) && (y >= 0 && y <= tam) ) {
         
            char[] aux = new char[y - x];
         
            for(int i=x, j=0; i<y; i++, j++) {
                aux[j] = this.str[i];
            }
         
            return aux;
        }
        return this.str;
    }
 
    public int comparar(char[] str1, char[] str2) {
        /*
         *  0  são iguais
         *  1  maior
         * -1  menor
         */
     
        int t1 = tamanho(str1);
        int t2 = tamanho(str2);
     
        if(t1 > t2) {return 1;} else if(t2 > t1) {return -1;}
        else {
            for(int i=0; i<t1; i++) {
                if(str1[i] > str2[i]) {
                    return 1;
                } else if(str2[i] > str1[i]) {
                    return -1;
                }
            }
            return 0;
        }
    }
 
    public void valueOf(char[] str) {
        for (char c : str) {
            System.out.print(c);
        }
    }
 
    private char[] espelha(char[] str) {
        int tam = tamanho(str);
        char[] x = new char[tam];
        for(int i=0; i<tamanho(str); i++) {
            x[i] = str[i];
        }
        return x;
    }
 
}
Bom pessoal postei para ajudar e não para copiar, a intenção é evolução e não regressão beleza!? Bons estudos!

terça-feira, 12 de março de 2013

Realizando leitura com System.in.read

Fala pessoal, hoje vou mostrar como realizar a leitura do teclado utilizando System.in.read(). Então teremos hoje mais um post dedicado aos programadores Java e ao pessoal que gosta de Java. Gostaria de alertar que a partir do Java 5 a leitura do teclado é feita com a classe Scanner do pacote java.util.Scanner.

Realizando leitura do teclado sem utilizar a classe Scanner

Como dito anteriormente nas versões anteriores da Java 5 a leitura do teclado exigia um certo esforço do programador. Antigamente o programador utilizava o método System.in.read() que retorna um InputStream bufferizado. Então o programador pegava este buffer retornado e convertia-o para caracter para que ele pudesse converte-lo para os demais formatos.

Exemplos práticos

Vou utilizar dois problemas apresentados na aula de POO do IFSP campus Araraquara curso ADS para ilustrar como é feita a leitura utilizando a classe System.in.read().
  1. Construa um programa Java que leia o ano de nascimento do usuário e calcule a idade do mesmo;
  2. Construa um programa Java que leia uma sigla para sexo (M/F) e depois apresente no console o sexo lido;
    Atenção: A leitura do teclado deve ser realizada com o método System.in.read();

SysRead2.java
import java.io.IOException; public class SysRead2 { public static void main(String[] args) throws IOException { byte[] aux = new byte[4]; System.out.println("Informe seu ano de nascimento: "); System.in.read(aux); int anoNascimento = Integer.parseInt(new String(aux, "UTF-8")); System.out.println("Idade: " + (2013 - anoNascimento)); } }

SysRead3.java
import java.io.*; public class SysRead3 { public static void main(String[] args) throws IOException { byte sexo; System.out.println("Informe o sexo M/F: "); sexo = (byte) System.in.read(); System.out.println("Sexo digitado: " + (char)sexo); } }

Dúvidas e sugestões deixem comentários, Bons estudos.

domingo, 3 de março de 2013

Porque não utilizar o DefaultTableModel

Olá pessoal, hoje vamos falar de TableModel e porque não devemos utilizar o DefaultTableModel em sua JTable.
Para que o leitor compreenda o assunto tratado é necessário que o mesmo tenha conhecimento dos princípios básicos de POO e que conheça o funcionamento do toolkit para construções gráficas swing.

Nem sempre o modelo pronto é o mais fácil

Muitas vezes quando estamos trabalhando com JTable não nos preocupamos em implementar o modelo da Table e simplemente utilizamos o modelo padrão (DefaultTableModel). O DefaultTableModel é um modelo padrão utilizado para que o programador possa adaptá-lo a suas necessidades. Mas nem sempre adaptar esse TableModel padrão é uma boa escolha, na maioria das vezes o DefaultTableModel deixará o desempenho da aplicação comprometido assim como a segurança da mesma.

A situação pode ficar ainda pior, vamos supor que você tenha feito um software a 3 anos atrás e nesse software você persistio as informações com JDBC, porém, agora você deseja migrar para um ORM de sua proferencia, por exemplo Hibernate. Você terá que percorrer linha por linha da JTable e mapear as informações para objetos e depois montar um List para então poder salvar os dados contidos em sua JTable.

Por esse e outros motivos a melhor solução seria a implementação de um TableModel para cada JTable de sua aplicação e abolir de vez o uso do DefaultTableModel.

Implementando um TableModel simples

Sempre quando procuramos ajuda na Internet o pessoal escracha o DefaultTableModel e manda a pessoa implementar um TableModel e se quer diz como a pessoa deve fazer.

Veja a implementação de um TableModel para sua JTable:


public class TableModelOrdemServico extends AbstractTableModel { private String[] colunas = new String[]{"Descrição", "Qtde"};//aqui vc coloca os nomes que iram aparecer na coluna de sua JTable, o número de colunas é igual ao número de elementos que contem no Array private Class[] classeColuna = new Class[]{String.class, Integer.class};//aqui vc coloca o tipo de dado que cada coluna armazena. Os tipos suportados são: Integer, Double, String e Object. private List linhas;//Cada elemento do List representa uma linha da JTable, então quando um novo elemento é adicionado na tabela ele também é adicionado no List. public TableModelOrdemServico() { linhas = new ArrayList<>(); } public TableModelOrdemServico(List listaDeItensDeVenda) { this(); linhas.addAll(listaDeItensDeVenda); } @Override public String getColumnName(int columnIndex) {//Retorna o nome da coluna return colunas[columnIndex]; } @Override public int getColumnCount() {//Retorna o número de colunas que seu modelo tem. Repare que o número de colunas é igual ou tamanho do Array. return colunas.length; } @Override public int getRowCount() {//Retorna o número de linhas que o modelo da tabela tem. Repare que o número de elementos corresponde ao número de linhas do modelo return linhas.size(); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) {//Retorna qual célula da tabela é editável, nesse exemplo nenhuma célula é editável return true; } @Override public Class getColumnClass(int columnIndex) {//Retorna a classe da coluna selecionada return classeColuna[columnIndex]; } @Override public Object getValueAt(int rowIndex, int columnIndex) {//Retorna o valor contido da célula OrdemServico o = linhas.get(rowIndex); switch(columnIndex) { case 0: return o.getDescricao(); case 1: return o.getQtde(); default: return null; } } @Override public void setValueAt(Object obj, int rowIndex, int columnIndex) {//Modifica/Atualiza o valor contido na célula. OrdemServico o = linhas.get(rowIndex); switch(columnIndex) { case 0: o.setDescricao(obj.toString()); break; case 1: o.setQtde(Integer.parseInt(obj.toString())); break; case 2: o.setQtde(Integer.parseInt(obj.toString())); break; } fireTableDataChanged(); } //Os métodos listados acima devem ser reescritos em cada classe que extenda AbstractTableModel (se vc não entende o que a palavra extends representa em Java leia sobre Herança aqui no Blog temos um POST explicando sobre o assunto). //Você ainda pode implementar quantos métodos forem necessários para sua aplicação

Espero que tenham gostado e até a próxima pessoal.

domingo, 27 de janeiro de 2013

Programando em Java - parte 15

Métodos e classes finais (final)

Você deve estar se lembrando do modificador final que é utilizado em variáveis quando desejamos que o valor seja o mesmo durante toda a execução do programa (constantes). Além de poder ser utilizado em variáveis podemos utilizar esse cara em métodos e classes.

Métodos

Métodos final não podem ser sobrescritos nas subclasses que implementam sua superclasse. Uma declaração do método final nunca pode mudar, sendo assim todas as subclasses utilizam a mesma implementação do método.

final void parar() { //lógica para parar o que você quiser }

Classes

Uma classe final não pode ser estendida. Esta é uma medida de segurança da linguagem Java que impede a criação de subclasses mal-intencionadas afim de driblar a segurança do sistema.

public final class Autor { //essa classe não pode ser superclasse }
Chegamos ao final de mais um assunto, espero que tenham gostado de aprender sobre classes e métodos finais. Até a próxima.

Programando em Java - parte 14

Classes abstratas

Já vimos que em Java podemos criar classes genéricas e estende-las criando classes mais especificas (herança). Também vimos que podemos modificar os comportamentos da classe padrão em cada classe especifica (polimorfismo). Na maioria das vezes a função da classe genérica é apenas fornecer um "modelo" para que as classe filhas implementem, sendo assim não seria necessária a instanciação dessa classe genérica.

Em Java podemos criar classes que não podem ser instanciadas. Dizemos que temos dois tipos de classe: concretas (podem ser instanciadas) e não concretas (não podem ser instanciadas). Para criar uma classe abstrata em Java utilizamos a palavra reservada abstract.

Uma classe abstrata pode conter métodos abstratos e métodos não abstratos, porém, uma classe que não é abstrata não pode conter nenhum método abstrato. Métodos abstratos não fornecem implementações.

A classe concreta que implementar a superclasse abstrata deve implementar os métodos abstratos da mesma. Construtores e métodos estáticos (static) não devem ser abstratos. O construtor não é herdado, portanto nunca seria sobrescrito. Métodos estáticos não podem ser reescritos portanto não faz sentido que o mesmo seja abstrato.

Exemplo:

Criação da classe abstrata Transporte.
public abstract class Transporte { String cor, int ano; abstract void parar(); }
Criação da classe Moto.
public class Moto extends Transporte { String cor, int ano; @Override void parar() { //lógica para parar a moto } }
Criação da classe Navio.
public class Navio extends Transporte { String cor, int ano; @Override void parar() { //lógica para parar o navio } }
Com isso garantimos que todas as classes que implementarem a classe Transporte implementaram o método parar. Bom com isso encerramos mais um conteúdo, até a próxima pessoal.

sexta-feira, 25 de janeiro de 2013

Métodos - Parâmetros com tamanho indefinido

Introdução

Olá pessoal, muitas vezes estamos construindo uma aplicação em que não sabemos exatamente quantos parâmetros de um mesmo tipo o método vai ter em sua chamada (quando ele for acionado). Para solucionarmos este problema poderiamos declarar um vetor do tipo que desejado e passá-lo como parâmetro, porém, em Java temos uma forma mais elegante de se passar um número de parâmetros indefinido para os métodos. Vejamos como podemos faze-lo.

Passando um número indefinido de parâmetros

Como dito anteriormente a linguagem Java suporta a passagem de um número indefinido de parâmetros. Para fazer isso basta utilizar três pontos ( ... ) após a declaração do tipo da variável e logo após dos três pontos colocar o nome da variável. Quando isso é o compilador cria um array contendo os valores que foram passados por parâmetro. Exemplo:

public class App { static void tabuadaDo2(int ... num) { for(int n : num) { System.out.println(n + " x 2 = " + n*2); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 tabuadaDo2(new int[]{1,2,3,4,5,6,7,8,9,10}); } }

Só é permitida a inclusão de uma parametro indefinido por método, pois, o parametro indefinido deve estar no fim do método (ultimo a ser declarado).  Exemplo;

public class App { static void tabuadaDo2(int ... num, double ... numeros) {//não compila for(int n : num) { System.out.println(n + " x 2 = " + n*2); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 int[] list = {2,3,4,5,6,7,8,9,10}; tabuadaDo2(list); } }

É importante ressaltar que apenas variaveis indefinidas tem que serem unicas! Portanto um parametro indefinido pode fazer parte de um metodo que tenha mais de uma variavel de parametro. Exemplo:

public class App { static void tabuadaDo2(double numeros, int ... num) { for(int n : num) { System.out.println(n + " * " + numeros + " = " + n*numeros); } } public static void main(String[] args) { tabuadaDo2(2,3,4,5,6,7,8,9,10);//podemos chamar passando os valores 1 à 1 tabuadaDo2(new int[]{9,73,4,67,1,0}); } }

Espero que tenham gostado pessoal, qualquer coisa deixem um comentário. Até mais!!!

quarta-feira, 23 de janeiro de 2013

Resolução dos exercícios de matrizes em Java

Exercício 1. Crie um programa Java que receba duas matrizes como entrada de dimensões N:M (importânte que sejam tamanhos genéricos usuário deve definir). Ao termino da leitura programa deve calcular a multiplicação entre essas matrizes.

package matriz; import java.util.Scanner; public class MultiplicacaoDeMatrizes { private static Scanner s; /** * @param args */ public static void main(String[] args) { //variáveis usadas para ler as dimensões que a matriz terá int n, m; s = new Scanner(System.in); System.out.println("Informe o número de linhas da primeira matriz"); n = s.nextInt(); System.out.println("Informe o número de colunas da primeira matriz"); m = s.nextInt(); //declaração da primeira matriz int[][] m1 = new int[n][m]; System.out.println("Informe o número de linhas da segunda matriz"); n = s.nextInt(); System.out.println("Informe o número de colunas da segunda matriz"); m = s.nextInt(); //declaração da segunda matriz int[][] m2 = new int[n][m]; /* * A multiplicação de matrizes só é possível se o número de colunas dem1 for igual ao número de linhas de m2 * * Exemplo de matrizes que são multiplicaveis entre si: * * m1 = 4x1 m2 = 1x4 * m1 = 2x2 m2 = 2x10 * * Exemplo de matrizes que NÃO são multiplicáveis entre si: * * m1 = 3x3 m2 = 4x1 * m1 = 2x8 m2 = 2x8 * * Então antes de multiplicarmos as matrizes propriamente ditas, devemos conferir se o número de colunas de m1 é igual ao número * de linhas de m2. * */ if (m1[0].length != m2.length) { //se número de colunas de m1 for diferente de número de linhas de m2 então não pode multiplicar System.out.println("As matrizes não são multiplicáveis entre si!!!"); System.exit(1); //aborta o programa retornando um erro } else { //caso contrário, se forem iguais ai podemos multiplicá-las //realizar o preenchimento das matrizes System.out.println("Preenchendo a primeira matriz!"); for(int i = 0; i < m1.length; i++) { for(int j = 0; j < m1[0].length; j++) { System.out.println("Informe um valor: "); m1[i][j] = s.nextInt(); } } System.out.println("Preenchendo a segunda matriz!"); for(int i = 0; i < m2.length; i++) { for(int j = 0; j < m2[0].length; j++) { System.out.println("Informe um valor: "); m2[i][j] = s.nextInt(); } } //devemos declarar uma terceira matriz que será o resultado da multiplicação entre as matrizes (produto das matrizes m1 x m2) int[][] m3 = new int[m1.length][m2[0].length]; //multiplicando as matrizes /* * Os 2 primeiros for's representados por i e j respectivamente serão responsáveis por controlar o índice da matriz m3. * Já o terceiro for 'k', é responsável por perconrrer todos os elementos da horizontal e vertical das duas matrizes. * * */ for (int i = 0; i < m1.length; i++) { for (int j = 0; j < m1.length; j++) { for (int k = 0; k < m2.length; k++) { m3[i][j] += (m1[i][k] * m2[k][j]); } } } //imprimindo a matriz gerada for(int i = 0; i < m3.length; i++) { for(int j = 0; j < m3.length; j++) { System.out.print(m3[i][j] + "\t"); } System.out.println(); } } } }
Exercício 2.(Desafio) Crie um programa Java que seja capaz de ler informações de N funcionários da Google, o programa deve armazenar: Nome (String), Apelido (String), Idade (int), código (int). Já sabemos que matrizes em Java são homogêneas portanto só conseguem guardar um tipo único de dados. O programa deve exibir os N funcionários em ordem crescente por idade.

package matriz; import java.util.Scanner; public class OrdenacaoDeMatrizes { private static Scanner s; /** * @param args */ public static void main(String[] args) { s = new Scanner(System.in); String[][] m1 = new String[3][2]; int[][] m2 = new int[3][2]; for(int i = 0; i < 3; i++) { System.out.println("Informe o nome do " + (i+1) + "º funcionário: "); m1[i][0] = s.next(); System.out.println("Informe o apelido do " + (i+1) + "º funcionário: "); m1[i][1] = s.next(); System.out.println("Informe o código do " + (i+1) + "º funcionário: "); m2[i][0] = s.nextInt(); System.out.println("Informe a idade do " + (i+1) + "º funcionário: "); m2[i][1] = s.nextInt(); } /* * Utilizando o método de ordenação Bubble Sort * */ for(int i = 0; i < 3; i++) { for(int j = i; j < 3; j++) { if(m2[i][1] > m2[j][1]) { //Se o próximo elemento for maior então devemos trocar de lugar com seu antecessor String nome, apelido; int codigo, idade; //armazenando o maior (guarda os valores do antecessor) nome = m1[i][0]; apelido = m1[i][1]; codigo = m2[i][0]; idade = m2[i][1]; //maior recebe o menor (antecessor recebe próximo) m1[i][0] = m1[j][0]; m1[i][1] = m1[j][1]; m2[i][0] = m2[j][0]; m2[i][1] = m2[j][1]; //menor recebe maior (próximo recebe seu valores guardados) m1[j][0] = nome; m1[j][1] = apelido; m2[j][0] = codigo; m2[j][1] = idade; } } } //exibindo os dados ordenados em ordem crescente por idade for(int i = 0; i < 3; i++) { System.out.println("Nome: " + m1[i][0]); System.out.println("Apelido: " + m1[i][1]); System.out.println("Código: " + m2[i][0]); System.out.println("Idade: " + m2[i][1]); System.out.println(); } } }

Matrizes em Java

Olá pessoal, estava dando uma olhada em minhas publicações e percebi que estava faltando explicar sobre matrizes na linguagem Java. Bom vamos lá então.
Dica: Antes de ler sobre Matrizes em Java leia esse post que fala sobre vetores (arrays unidimensionais).


Cotidiano com matriz

Matriz por definição é um array multidimensional, ou seja, um array de várias dimensões. Para aplicações em nível de softwares comerciais dificilmente você irá empregar o uso de mais de duas dimensões em um array. Para declarar um array de 2D (duas dimensões) em Java fazemos:

int[][] array2D = new int[2][2];

Nesse exemplo foi declarado um array de "quadrado" de duas linhas e duas colunas. Um array 2D pode ser de vários tipos: String, float, int, double, porém, ele deve ser heterogêneo não podendo armazenar dados de tipos diferentes. Se o array foi declarado do tipo String então suas linhas e colunas devem armazenar somente valores do tipo String.

A solução para armazenar dados de diferentes tipos em matrizes (arrays multidimensionais) é a criação de outras matrizes e fazer a leitura associadamente. Por exemplo, suponha que você tenha que armazenar o nome, endereço, idade e código de um contato. Sabendo que código e idade são tipos inteiros de dados (int) e que nome e endereço são tipos caracteres de dados (String) como armazenar essas informações? Veja:

String[][] caracteres = new String[4][2]; int[][] inteiros = new int[4][2]; caracteres[0][0] = nome; caracteres[0][0] = endereco; inteiros[0][0] = codigo; inteiros[0][1] = idade
Dessa forma conseguimos guardar dados referentes a um mesmo contato em diferentes matrizes de diferentes tipos de dados. Para acessar todas as informações de um determinado contato basta informamos o mesmo número de linha para as duas matrizes, isso retorna todas as informações referentes ao contato procurado.

Vamos imaginar agora que nossa matriz tenha um número muito grande de elementos e que acessar ela índice por índice seria uma tarefa árdua e muito trabalhosa. Para percorrer uma matriz podemos utilizar a estrutura de repetição for. Veja como fica:

for(int i = 0; i < 4; i++) {     for(int j = 0; j < 2; j++) {         System.out.println(caracteres[i][j]);         System.out.println(inteiros[i][j]);     } }

Bom tudo o que foi apresentado até agora resolve muito bem o seu problema quando você conhece previamente o tamanho que a matriz tem. Mas e se você não souber o tamanho do matriz?

Quando não sabemos o tamanho da matriz o código fica um pouco mais complexo, mais nada que chega a assustar. Em Java podemos declarar o array sem fornecer um tamanho para ele, veja:

int[][] inteiros;
O que fizemos acima foi dizer a JVM que teremos um Array de duas dimensões, porém, não construímos esse array ainda portanto ele não pode ser utilizado. Agora devemos obter o tamanho que nosso array deve ter para então criarmos e utilizarmos ele. Veja o exemplo:

int r = (int) (Math.random()*100); //gera um número aleatório entre 0 e 99 inteiros = new int[r][r];

Beleza e agora para percorrermos o array devemos utilizar o tamanho armazenado em r, ou podemos utilizar um método para descobrir qual é esse tamanho. Para descobrir quantas linhas e colunas uma array multidimensional tem utilizamos o método length, veja:

inteiros.length; //retonar o número de linhas
inteiros[0].length; //retorna o número de colunas

Agora veja como podemos percorrer a matriz utilizando o método length:

for(int i = 0; i < inteiros.length; i++) {     for(int j = 0; j < inteiros[i].length; j++) {         System.out.println(inteiros[i][j]);     } }

Lembrando que para exibir somente a linha ou coluna de uma matriz podemos deixar o número fixo no índice e usar o for para percorrer dinamicamente os demais índices do array, veja:

//exibindo todos os elementos da linha 0 for(int coluna = 0; coluna < inteiros[0].length; coluna++) {     System.out.println(inteiros[0][coluna]); }
//exibindo todos os elementos da coluna 1 for(int linha = 0; linha < inteiros.length; linha++) {     System.out.println(inteiros[linha][1]); }


Pessoal seguem dois desafios abaixo para tentarem solucionar, tentam solucionar e dúvidas postem comentários. Vou postar o link com a resolução dos exercícios mais tarde. Abraço a todos!

Dica: comentar código é uma boa prática de programação.

  1. Crie um programa Java que receba duas matrizes como entrada de dimensões N:M (importânte que sejam tamanhos genéricos, usuário deve definir). Ao termino da leitura programa deve calcular a multiplicação entre essas matrizes (produto de matrizes).
  2. (Desafio) Crie um programa Java que seja capaz de ler informações de N funcionários de uma empresa, o programa deve armazenar: Nome (String), Apelido (String), Idade (int), código (int). Já sabemos que matrizes em Java são homogêneas portanto só conseguem guardar um tipo único de dados. O programa deve exibir os dados dos N funcionários em ordem crescente por idade.

domingo, 13 de janeiro de 2013

Programando em Java - parte 13

Polimorfismo

Polimorfismo, é uma palavra de origem grega que siginifica "muitas formas". Em POO polimorfismo é a capacidade de objetos de classes diferentes responderem a mesma mensagem de diferentes maneiras.

Vejamos o seguinte exemplo:
Uma empresa de tecnologia resolveu desenvolver um controle universal que poderá controlar qualquer tipo de aparelho eletrônico, cada aparelho atende os comandos especificos definidos por ele. 

Segundo Jun Matsumoto (gerente da empresa) o controle remoto teria vários botões, sendo que todos eles seriam úteis para todos os aparelhos. Assim quando o usuáiro clicasse no botão ligar, todos os aparelhos que estivesse em um raio de 1,5m ligariam. 

Jun ainda acrescenta que cada aparelho se comportará de acordo com a sua função, ou seja, quando solicitamos via controle que os aparelhos liguem cada um ligara de acordo com as suas caracteríscas já que a geladeira liga de uma forma, o forno microondas de outra e assim em diante.
Repare que os aparelhos respondem ao mesmo sinal de formas diferentes, temos aqui um caso de POLIMORFISMO.


Tipos de polimorfismo

O polimorfismo pode ser classificado de 3 maneiras:
  1. Sobrecarga ( se você ainda não leu de uma paradinha e aproveite para esclarecer suas dúvidas)
  2. Sobreposição ( leia a seção Reecrita de Métodos, aproveite esse momento caso você não tenha lido )
  3. Inclusão
Vamos implementar o código e em seguida explicaremos o conceito de inclusão.

public class Aparelho { public void ligar () { System.out.println ("Ligar aparelho"); } }
public class TV extends Aparelho { public void ligar () { System.out.println ("Ascender tela"); } }
public void Torradeira extends Aparelho { public void ligar () { System.out.println ("Ascender luz on"); } }
public void Microondas extends Aparelho { public void ligar () { System.out.println ("Piscar luz de ativo"); } }
public class Controle { private Aparelho aparelho; public Controle (Aparelho aparelho) { this.aparelho = aparelho; } public void ligar () { aparelho.ligar (); } }
public class Principal { public static void main (String[] args) { Tv tv = new Tv ()/ Controle controle = new Controle (tv); controle.ligar (); } }

Polimorfismo de inclusão usa a capacidade de substituição da Herança, de uma classe mãe por qualquer classe descendente, para permitir um comportamento polimórfico nos métodos que usam a classe mãe.
No exemplo visto a cima,veja a classe Principal,  onde criamos um objeto do tipo TV e outro do tipo Controle, nós utilizamos o comportamento polimórfico do polimorfismo de inclusão. Fizemos isso quando substituímos a classe Aparelho (mãe) pela classe TV (filha) dentro da classe Controle. Assim, o atributo interno do tipo Aparelho da classe Controle pode receber qualquer objeto que seja de uma classe filha de Aparelho.

domingo, 2 de dezembro de 2012

Programando em Java - parte 12

Herança

Na programação orientada a objetos temos o recurso de herança, que nada mais é que abstrair uma classe o mais genericamente possível e escrever outras classes mais especificas aproveitando os comportamentos e atributos da classe genérica. A ideia da herença é aumentar a produtividade na escrita do código e também deixar o código mais limpo, evitando a redundancia de código entre as classes (código repetido).
Como todo conceito da POO não é explicitamente obrigatório o uso de herança em seu código também não, porém, não usá-lo significa quebra conceitual.

Uma classe que faz tudo!

Muitos programadores acham que é beneficio criar uma classe que faça completamente tudo em seu sistema. Não há problema algum em declarar todas as funcionalidades de um sistema dentro de uma classe. No entanto, seu código fica muito mais complexo e a dificuldade de manutenção aumenta muito. Vejamos como poderiamos resolver o mesmo problema primeiramente sem utilizar a herança, depois utilizando a herança de forma errada e por fim aplicando a herança corretamente.

Classe animal.java


Olá meu nome é Juca! 
Preciso de um sistema que cadastre meus bichos de estimação. Sabe senhor programador eu sou um cara muito versátil quando se fala de animais, eu gosto de: cachorros, gatos, lagartos, passáros, tartarugas .. Preciso de um sistema bom, barato e que me entregue o mais rápido possível OK?!

Bom, muitas vezes você vai se deparar com os Jucas da vida, e a pergunta é como os maus programadores fariam esse sistema? Será que eles usariam Herança? Vamos para o exemplo:

public class BichoEstimacao {
// geral
private Animal animal;
private String nome;
private Date aniversario;
// mamiferos
private String corPelo;
private int nroGlandulasMamaria;
// repteis
private float temperaturaCorporal;
private String corEscama;
// métodos
}

Bom apesar de resolver todos os nossos problemas quanto a modelagem do sistema, programar todas as funcionalidades em apenas uma classe pode dificultar o desenvolvimento. Supondo que dois ou mais desenvolvedores são responsáveis pela implementação dos bichos de estimação, provavelmente eles modificariam a mesma classe em paralelo. Além disso, os desenvolvedores ficariam  confusos ao abrirem o código dessa classe.

Uma classe para cada animal

Para modelar melhor os animais, evitando uma quantidade grande de atributos e métodos desnecessários, criaremos uma classe para cada Animal.

public class Gato {
    // geral
    private Animal animal;
    private String nome;
    private Date aniversario;
    // gato
    private String corPelo;
    private int nroGlandulasMamarias;
    private String raca;
}


public class Tiu {
    // geral
    private Animal animal;
    private String nome;
    private Date aniversario;
    // tiu
    private String corEscama;
    private float temperaturaCorpo;
    private boolean chocando;
}

Criar uma classe para cada animal torna o sistema mais flexível, pois qualquer alteração em um determinado serviço não causará efeitos colaterais nos outros. Porém, essas classes apresentam redundância de código e sabemos que a herança veio para abolir isso! E pior, qualquer alteração que seja comum a todos os animais deverá ser implementada classe por classe. Isso quer dizer que ainda estamos errando em alguma coisa.

Uma classe genérica e várias específicas

Na modelagem dos animais do sistema do Juca, podemos aplicar o conceito de Herança. A ideia consiste em reutilizar o código de uma classe em N classes.
Aplicando herança a esse sistema, vamos ter uma classe BichoEstimacao com todos os atributos e métodos comuns à um animal de estimação, e vamos ter uma classe mais específica detalhando as caracteristicas e comportamentos que cada animal possui.
As classes Gato e Tiu seriam "relacionadas" a classe BichoEstimacao para poder reaproveitar o seu código já definido. Veja a representação UML abaixo:


Os objetos das classes específicas Gato e Tiu possuirão tanto os atributos e métodos definidos em suas respectivas classes quanto os definidos na classe BichoEstimacao. Dizemos que BichoEstimacao é a classe pai, e a Gato e Tiu são suas classes filhas. 
Para "associar/ligar" uma classe especifica a uma classe genérica em Java, utilizamos o comando extends. Não é necessário redefinir o conteúdo já declarado na classe genérica.

public class BichoEstimacao {
    // geral 
    private Animal animal;
    private String nome;
    private Date aniversario;
}

public class Gato extends BichoEstimacao {
    // gato
    private corPelo;
    private nroGlandulasMamarias;
    private raca;
}

public class Tiu extends BichoEstimacao {
    // tiu
    private String corEscama;
    private float temperaturaCorpo;
    private boolean chocando;
}

As classes filhas podem acessar todos os métodos e atributos de seu pai. Java não dá suporte a herança multipla, ou seja, para a Java um Pai pode ter vários filhos já os filhos são de um único pai. Esse pensamento traduzido para vida real é muito lógico já que um filho tem um único pai biológico e esse pai pode ter vários filhos.

Gato mimo = new Gato();
//chamada a um método da classe BichoEstimacao
mimo.setNome = "Mimo";
//chamada a um método da classe Gato
mimo.setRaca = "Angora";

Calcular idade

Todos os animais possuim uma idade certo? Vamos considerar inicialmente que para todos animais o calculo de idade é o mesmo. Sendo assim poderiamos implementar um método na classe BichoEstimacao para calcular a idade dos animais. Este método será reaproveitado por todas as classes que herdam da classe BichoEstimacao.

public class BichoEstimacao {
// atributos public int calculaIdade(int anoNascimento, int anoAtual) { return anoAtual - anoNascimento; }  }

BichoEstimacao bicho = new BichoEstimacao();
Gato megui = new Gato();
System.out.println("Idade: ", + bicho.calculaIdade(2010,2012));
System.out.println("Idade: ", + megui.calculaIdade(2012,2012));

Reescrita de método

Como sabemos cada animal representa uma idade diferente ao calculo da idade humana, alguns animais possuem um envelhicimento mais tardio e outros mais recentes. Como essa lógica é específica de cada animal devemos implementar esse calculo na classe BichoEstimacao.

class Gato extends BichoEstimacao {
// atributos
public int calcIdadeGato(int anoNascimento, int anoAtual) {
return (anoAtual - anoNascimento) * 7 ;
}

Para os objetos da classe Gato devemos chamar o método calcIdadeGato. Para todos os outros animais devemos chamar o método calculaIdade.

Mesmo assim isso não impederia que o método calculaIdade fosse chamado de um objeto da classe Gato, pois este método é herdado da sua classe Pai BichoEstimacao. Deste modo existe o risco de acidentamente invocarmos o método errado.

O correto é substituir a implementação do método calculaIdade(int anoNascimento, int anoAtual) herdado da classe BichoEstimacao na classe Gato. Para isso, basta escrever o método calculaIdade(int anoNascimento, int anoAtual) também na classe Gato do mesmo jeito que ela foi definida na classe Pai (BichoEstimacao), ou seja, com a mesma assinatura.

class Gato extends BichoEstimacao {
// atributos
public int calculaIdade(int anoNascimento, int anoAtual) {
return (anoAtual - anoNascimento) * 7 ;
}

Os métodos das classes filhas tem prioridade sobre os métodos da classe pai. Se o método chamado existe na classe filha ele será chamado, caso contrário se ele não exister será procurado sua existencia na classe Pai.

domingo, 23 de setembro de 2012

Programando em Java - parte 11

Encapsulamento

Encapsulamento é uma técnica usada no paradigma Orientado a Objetos afim de centralizar e facilitar a busca de eventuais erros contidos no código. 

Exemplo:

public class Gato {     String raca; }
No exemplo acima, o atributo raça pode ser acessado e modificado em qualquer classe que esteja no projeto em que a classe Gato foi criada. Quando isso ocorre dizemos que o controle é descentralizado.
Para identificarmos e corrigirmos possíveis erros relacionados a raça do gato teremos que analisar todo o projeto já que a raça é visível ao projeto todo.
Vamos nos deparar muito com essa palavra "visibilidade", isso quer dizer "quem tem permissão para realizar a manipulação daquele atributo".
Para resolvermos este problema e criarmos o chamado controle centralizado devemos tornar o atributo raca privado e implementar métodos publicos que implementem toda a lógica de manipulação necessária desse atributo.
Os atributos devem ser privados porque todo atributo privado só pode ser acessado ou alterado pela classe que ele está contido, ou seja, o atributo raca só pode ser alterado por código que esteja contido na classe Gato. E o contrário nunca poderá ser feito, se alguma outra classe que não seja a Gato tentar acessar o atributo raca, um erro de compilação será gerado.
Os métodos devem ser publicos para que as demais classes consigam acessá-los. Definir todos os atributos como privado e métodos publicos que implementem a lógica de manipulação dos atributos, é praticamente uma regra em Orientação a Objetos. Isso é feito para que o controle seja centralizado, facilitando a manutenção e detecção de erros.

Gato.java public class Gato {
    private raca;
   
    public void mudarRaca(String raca) {
        this.raca = raca;
    }
}

 

Métodos Privados

Nem sempre os métodos deveram ser visíveis a todas as classes do seu projeto, às vezes o método tem papel de auxiliar outros métodos que estejam na mesma classe. Nesse caso seria um erro chamar este método fora da classe em que ele foi escrito.
No exemplo abaixo o método atribuiIp() é um método auxiliar de entrarRede(), sairRede(). Sendo assim ele não deve ser chamado diretamente, pois a atribuição de ip só deve ocorrer quando ele entrar na rede.

Rede.java
public class Rede {
    void connectar() {
        //lógica para criar conexão
    }
   
    void desconectar() {
        //lógica para desconectar da rede
    }
   
    String atribuirIp() {
        //lógica para retornar um número IP válido na rede
    }
}

Para garantir que não será possível a chamada do método atribuirIP() fora da classe Rede, devemos adicionar o modificador private. 

public class Rede {
    void connectar() {
        //lógica para criar conexão
    }
   
    void desconectar() {
        //lógica para desconectar da rede
    }
   
    private String atribuirIp() {
        //lógica para retornar um número IP válido na rede
    }
}

Agora qualquer chamada ao método atribuirIP() que não seja feita pela classe Rede, acarretará um erro de compilação garantindo assim que nosso método só será chamado dentro da classe Rede.

Métodos Públicos

Todos os métodos que devem ser acessados fora da classe de origem devem conter o modificador de acesso public. O public diz ao compilador que o método pode ser acessado por qualquer objeto que esteja no projeto em que o método chamado se encontra.

public class Rede {
    public void connectar() {
        //lógica para criar conexão
    }
   
    public void desconectar() {
        //lógica para desconectar da rede
    }
   
    private String atribuirIp() {
        //lógica para retornar um número IP válido na rede
    }
}

Porque encapsular?

Encapsular é uma das principais funcionalidades da programação orientada a objetos. Encapsular seria esconder o código de implementação e apenas mostrar a interface de uso do método.
O encapsulamento de dados nos ajuda na manutenção e no desenvolvimento do sistema, uma vez que com ele as tarefas ficam melhores divididas entre as classes e quando devemos modificar o comportamento dos objetos basta alterar a classe do objeto.
Para que você entenda melhor vamos fazer uma simples analogia ao mundo real utilizando o conceito de POO.

Imagine o controle remoto de sua televisão, a interface de uso seria os botões de: aumentar volume, abaixar volume, trocar de canal .. etc. Quando você usa o controle podemos dizer que você está usando a interface, porém, você não sabe como o serviço é feito. Você simplesmente aperta o botão e algo acontece, pois a implementação do serviço não é interessante, não é necessária conhecermos apenas queremos executar o serviço. Trazendo para a programação agora, o botão seria a assinatura do método = public void aumentarVolume(), e o serviço é o corpo do método, ou seja, o código que está escrito dentro dele. O código não deve ser visível ao objetos que vão acessar o método mais a assinatura do método deve ser visível aos demais objetos. Entendeu?

Getters e Setters

Aplicando a ideia do encapsulamento os atributos deveriam ser todos privados, com isso não seriam acessiveis por código que estivesse fora da classe em que foram definidos.
Mas na maioria dos sistemas as informações contidas nos atributos precisam ser acessadas e modificadas em qualquer parte do sistema. Nesse caso, podemos disponibilizar métodos para consulta e alteração de valores dos atributos.
Na linguagem Java, há uma convenção de nomenclatura para os métodos que tem como finalidade acessar ou alterar as propriedades de um objeto. Os métodos que tem como finalidade consultar as propiedades do objeto devem possuir o prefixo get, já os métodos que permitem a alteração das propriedades do objeto devem possuir o prefixo set.
Lembre-se bons programadores Java seguem a convenção.

public class Aluno {
    private String nome;

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

É isso ai pessoal! Dúvidas, sugestões, comentem ai...

sábado, 22 de setembro de 2012

Programando em Java - parte 10

Atributos e Métodos de Classe

Em um sistema muitas vezes é necessário que uma váriavel seja compartilhada por todos os objetos que venham a ser criados. Em Java temos os atributos e métodos de classe. Para criarmos métodos e atributos de classe utilizamos a palavra reservada staticUm atributo de classe por definição é publico então é redundante colocar o modificador de acesso public, já que por definição static é public também.
Vejamos um problema em que poderiamos aplicar uma solução utilizando atributo de classe:

Problema:
Imagine que uma montadora de veículos precise armazenar o número de carros fabricados por dia. A cada novo carro criado o sistema deve contabilizar o carro para que no final do dia possa exibir a quantidade de veículos criados.

Solução:

Montadora.java
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;

public class Montadora {
    public static void main(String[] args) {
        Carro.numCarros = 0;//inicializando o valor da variável
       
        for(int i=0; i<10;i++)
            new Carro();
           
        JOptionPane.showMessageDialog(null, "Foram fabricados " + Carro.numCarros + " carros.");
        JOptionPane.showMessageDialog(null, "Data: " + new SimpleDateFormat("dd/MM/yyyy").format(new Date()));
    }
}

Carro.java
public class Carro {
    static int numCarros;
   
    public Carro() {
        numCarros++;
    }
}

Para acessar variáveis de classe utilizamso o nome da classe, em seguida o operador ponto final (.) e o nome da variável que queremos acessar.

O correto para manipular atributos de classe é criarmos métodos de classe com a finalidade de controlar os valores contidos nesses atributos. Como a variável é publica e visível por todas as classes do nosso projeto não é explicitamente obrigatória a criação dos métodos de classe para fazer o controle dos mesmos, porém, fazer o manusei dos atributos de classe sem o uso de métodos é uma má prática de programação e consiste em um erro conceitual.

Problema 2:
Os funcionários da empresa GTi sistemas recebem vale refeição, todos os meses o valor do vale pode ser reajustado.

Solução:

Funcionario.java public class Funcionario {
    private String nome;
    static float valeRefeicao;
   
    public Funcionario(String nome) {
        this.nome = nome;
    }
   
    static void reajusteValeRefeicao(float valor) {
        valeRefeicao = valor;
    }
}

EmpresaGTi.java public class EmpresaGTi {
    public static void main(String[] args) {
        Funcionario programador = new Funcionario("Guilherme");
        Funcionario rh = new Funcionario("Débora");
        Funcionario analista = new Funcionario("Luiz");
       
        Funcionario.reajusteValeRefeicao(20);//todas as instancias de funcionário compartilham da mesma variável valeRefeicao
       
        //ERRO...
        programador.valeRefeicao = 20;//é possivel, porém, é erro conceitual
    }
}

Dúvidas , sugestões comentem...

Programando em Java - parte 9

Arrays

Quando desejamos armazenar uma grande quantidade de valores de um determinado tipo, podemos utilizar arrays. Um array é um objeto que pode armazenar muitos valores de um determinado tipo.
Podemos imaginar um array como sendo um armário com um determinado número de gavetas. E cada gaveta possui um rótulo com um número de identificação.

Criando um Array

Em Java, os arrays são criados através do comando new.

int numeros = new int[100];

Podemos ter arrays de vários tipos. Assim como podemos instanciar de várias maneiras o array, acima mostrei uma das formas de se criar um array, veja como podemos declarar um array de formas diferentes em Java:

int numeros[]; //aqui declaro meu array, porém, não instancie. Se eu tentar usá-lo irá acontecer um erro

int numeros[] = new int[] {1,23,54,19};/*Esse tipo de declaração instancia meu array e já adiciona os valores que são passados entre as chaves. Esse tipo de declaração é usado quando o programador já sabe quais valores devem sem iniciados junto com o array*/

Utilizando as Classes Arrays e Collections

Uma das vantagens de se usar a linguagem Java é que já existem muitas coisas prontas, basta o programador pesquisar a API e conhece-lá conforme suas necessidades. Quando trabalhamos com arrays podemos contar com as Classes Arrays e Collections do pacote java.util. Essas classes possuem os seguintes métodos já definidos:
  • Método de pesquisa de elemento;
  • Método de ordenação;
  • Método de exibição de todos elementos;
  • Método de inversão de ordem dos elementos contidos no array;
Exemplo:
import java.util.Arrays;
import java.util.Collections;
import javax.swing.JOptionPane;

public class ArraysExemplo {
    public static void main(String[] args) {
        String profInf[] = new String[] {"Renata", "Luiz", "Edilson", "Ednilson", "Janaina", "Gislaine", "Fábio", "Eduardo", "Francisco", "José Arnaldo"};
       
        //método bynarySearch retorna um int que condiz com a posição do elemento buscado no array
        //método sort organiza o array em de forma crescente
        //método toString imprime o array converte o array em String e exibe o completo na tela
        //método reverse inverte a ordem do array
       
        JOptionPane.showMessageDialog(null,"Posição: " + Arrays.binarySearch(profInf, "Janaina"));
       
        Arrays.sort(profInf);
        JOptionPane.showMessageDialog(null, "Array de forma organizada crescente : " + Arrays.toString(profInf));
       
        Collections.reverse(Arrays.asList(profInf));
        JOptionPane.showMessageDialog(null, "Array de forma organizada invertida : " + Arrays.toString(profInf));
    }
}

PS = Todo bom programador deve conhecer os recursos que sua linguagem já oferece pronta, para que ele não fique "reinventando a roda". A API do completa e atualizado Java pode ser encontrada no site da Oracle.

Comparando a utilização de array em um programa Java

Abaixo temos 3 versões de um mesmo programa Java. A função desse programa é ler três valores informados pelo usuário referentes a peso. Ao termino da entrada de dados o programa deve exibir qual  o maior, menor e a lista de todos os pesos lidos.

Programadores que não sabem utilizar array, ou acha que é perda de tempo escreve códigos Java assim:

import javax.swing.JOptionPane;

public class ArraysExemplo1 {
    public static void main(String[] args) {
        float peso, x, y;
        /*
        * a variável peso irá armazenar o peso fornecedo pelo usuário durante a execução do programa
        * a variável x irá armazenar a pessoa mais pesada
        * a variável y irá armazenar a pessoa mais leve
        */
       
        //inicializando x e y com valores impossíveis... Lembrando que essa é uma técnica não aconselhável
        x = -1000;
        y = 10000;
       
        for(int i=0; i<3; i++) {
        //diferentemente de C, o comando for em Java pode conter a declaração e inicialização de variáveis em sua primeira parte
            peso = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
           
            if(peso > x)
                x = peso;
           
            if(peso < y)
                y = peso;
        }
       
        JOptionPane.showMessageDialog(null, "Mais pesado = " + x + "kg");
        JOptionPane.showMessageDialog(null, "Mais leve = " + y + "kg");
        //não tem como mostrar todos os pesos lidos   :(
    }
}


Programadores que sabem utilizar array, porém, não conhecem os recursos que a API os oferecem. Irá desenvolver um código Java semelhante a este:

import javax.swing.JOptionPane;

public class ArraysExemplo2 {
    public static void main(String[] args) {
        float peso[] = new float[3];
        float x, y;
        /*
        * a variável peso irá armazenar o peso fornecedo pelo usuário durante a execução do programa
        * a variável x irá armazenar a pessoa mais pesada
        * a variável y irá armazenar a pessoa mais leve
        */
        for(int i=0; i<3; i++) {
            peso[i] = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
        }
       
        //inicializando os valores de x e y, com o primeiro valor lido
        x = peso[0];
        y =  x;
       
        for(int i=1; i<3; i++) {
        //diferentemente de C, o comando for em Java pode conter a declaração e inicialização de variáveis em sua primeira parte
       
            if(peso[i] > x)
                x = peso[i];
               
            if(peso[i] < y)
            y = peso[i];
        }
       
        JOptionPane.showMessageDialog(null, "Mais pesado = " + x + "kg");
        JOptionPane.showMessageDialog(null, "Mais leve = " + y + "kg");
        JOptionPane.showMessageDialog(null, "Todos os pesos lidos = " + peso[0] + ", " + peso[1] + ", " + peso[2]);
    }
}


Bons programadores, escrevem códigos assim:

import javax.swing.JOptionPane;
import java.util.Arrays;

public class ArraysExemplo3 {
    public static void main(String[] args) {
        float peso[] = new float[3];

        for(int i=0; i<3; i++) {
            try {
                peso[i] = Float.parseFloat(JOptionPane.showInputDialog("Informe o peso"));
            } catch(NumberFormatException e) {
                JOptionPane.showMessageDialog(null, "Erro ao coverter o valor digitado!", "Erro", JOptionPane.ERROR_MESSAGE);
            }
        }
       
        Arrays.sort(peso);//ordena os valores digitados
       
        JOptionPane.showMessageDialog(null, "Mais pesado = " + peso[2] + "kg");
        JOptionPane.showMessageDialog(null, "Mais leve = " + peso[0] + "kg");
        JOptionPane.showMessageDialog(null, "Todos os pesos informados = " + Arrays.toString(peso));
    }
}


Bom pessoal, duvidas e sugestões comentem...

Novidade!!! Agora vamos ter canal no Youtube =D

Fala pessoal tudo beleza, estou sumido a correria está forte por aqui. Estou querendo dar um start em um projeto antigo que vem desde o temp...