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

Polimorfismo


O polimorfismo, que significa muitas formas, permite que uma mesma referência se comporte de formas diferentes. Utilizando corretamente o polimorfismo nós podemos fazer o código ficar mais claro, genérico e, portanto, reutilizável.

Veja um exemplo:

Suponhamos que temos uma superclasse chamada Pessoa:

public class Pessoa {
 
    public void nome() {
  
    }
}

E que temos duas subclasses com o nome de Estudante e Empregado:

public class Estudante extends Pessoa {
 
    public void nome() {
       System.out.println("Nome do estudante: Oberdan");
    }
}

public class Empregado extends Pessoa {

    public void nome() {
       System.out.println("Nome do empregado: Taylor");
    }
}

Agora, na nossa classe principal temos o seguinte código:

/* Perceba que o tipo da variavel é Pessoa , mas não referencia um objeto do
 * tipo Pessoa, mas sim um objeto Estudante ou Empregado, essa variavel ref
 * pode referenciar qualquer objeto que extends a classe Pessoa.
 */

public class ClassePrincipal {

    public static void main(String[] args) {

       Pessoa ref = new Estudante();
  
       ref.nome(); // Referencia um objeto da classe Estudante(); 
  
       ref = new Empregado();
  
       ref.nome(); // Referencia um objeto da classe Empregado();
   }
}

O polimorfismo permite que múltiplos objetos de diferentes subclasses sejam tratados como objetos de uma única superclasse, e que automaticamente sejam selecionados os métodos adequados a serem aplicados a um objeto em particular, baseado na subclasse a que ele pertença.

Herança

 Herança é uma forma de reutilização de softwares em que uma nova classe é criada absorvendo  membros de uma classe exixtentes e aprimorada com capacidades novas ou modificadas. Com a Herança, você pode economizar tempo durante o desenvolvimento de um programa baseando novas classes no software existente.

Ao herdar membros de uma classe exixtente, a classe que herdou é chamada de subclasse, e a que existia anteriormente chamada de superclasse.


Para ficar mais claros vamos partir para um exemplo: Imagine que estivéssemos implementando um programa que fosse utilizado em um concessionária de veículos. Esta concessionária vende carros de passeio, jipes e veículos utilitários. Para implementar as classes destes veículos poderíamos criar três classes distintas,

A seguir a classe Jipe:

public class Jipe {
 
    private String marca;
    private Double capacidadeTanqueCombustivel;
 
    // Métodos Get e Set do atributo capacidadeTanqueCombustivel
 
    public Double getTanqueCombustivel() {
       return capacidadeTanqueCombustivel;
    }
 
    public void setTanqueCombustivel(Double capacidadeTanqueCombustivel) {
       this.capacidadeTanqueCombustivel = capacidadeTanqueCombustivel;
    }
 
    // Métodos Get e Set do atributo marca
 
    public String getMarca() {
       return marca;
    }
 
    public void setMarca(String marca) {
       this.marca = marca;
    }
 
    // Método para representar a tração do Jipe
 
    public void ligarTracao4x4() {
       // Código aqui
    }
}

A classe que representa o nosso carro de passeio:

public class CarroPasseio {

    private String marca;
    private Double capacidadeTanqueCombustivel;
 
    // Métodos Get e Set do atributo capacidadeTanqueCombustivel
 
    public Double getTanqueCombustivel() {
       return capacidadeTanqueCombustivel;
    }
 
    public void setTanqueCombustivel(Double capacidadeTanqueCombustivel) {
       this.capacidadeTanqueCombustivel = capacidadeTanqueCombustivel;
    }
 
    // Métodos Get e Set do atributo marca
 
    public String getMarca() {
       return marca;
    }
 
    public void setMarca(String marca) {
       this.marca = marca;
    }
 
    // Método para representar o ar condicionado do carro de passeio
 
    public void ligarArCondicionado() {
       // Código aqui
    }
}

E, finalmente, a classe que representa o nosso veículo utilitário:

public class Utilitario {

    private String marca;
    private Double capacidadeTanqueCombustivel;
 
    // Métodos Get e Set do atributo capacidadeTanqueCombustivel
 
    public Double getTanqueCombustivel() {
       return capacidadeTanqueCombustivel;
    }
 
    public void setTanqueCombustivel(Double capacidadeTanqueCombustivel) {
       this.capacidadeTanqueCombustivel = capacidadeTanqueCombustivel;
    }
 
    // Métodos Get e Set do atributo marca
 
    public String getMarca() {
       return marca;
    }
 
    public void setMarca(String marca) {
       this.marca = marca;
    }
 
    // Método para representar o farol de milha do carro utilitário
 
    public void ligarFarolMilha() {
       // Código aqui
    }
}

Perceba que, nas linhas destacadas, temos as características que dizem respeito a apenas um dos tipos de veículos, isto é, no nosso modelo, apenas jipes têm tração 4x4, somente os carros de passeio têm opção de ligar o ar condicionado e os utilitários tem farol de milha.

Todas os demais estados e comportamentos são idênticos, na verdade para criar estas três classes foi realizado uma simples cópia e cola dos membros que são iguais. Agora, se a concessionária resolvesse criar mais 8 tipos de veiculos difrentes, teríamos que repetir todos esses códigos?

Na verdade nada disto seria necessário se nós tivéssemos utilizado corretamente o conceito de herança da programação Orientada a Objetos. Perceba que com exceção das características que estão grifadas todas as demais são comuns a todos os veículos, ou seja, é possível que tenhamos uma superclasse (classe Pai) Veiculo e que todas as demais herdem estas características comuns dela.

A nossa classe Veiculo ficaria da seguinte forma:

public class Veiculo {

    private String marca;
    private Double capacidadeTanqueCombustivel;
 
    // Métodos Get e Set do atributo capacidadeTanqueCombustivel
 
    public Double getTanqueCombustivel() {
       return capacidadeTanqueCombustivel;
    }
 
    public void setTanqueCombustivel(Double capacidadeTanqueCombustivel) {
       this.capacidadeTanqueCombustivel = capacidadeTanqueCombustivel;
    }
 
    // Métodos Get e Set do atributo marca
 
    public String getMarca() {
       return marca;
    }
 
    public void setMarca(String marca) {
       this.marca = marca;
    }
}

Tudo o que era comum a todos os veículos foi concentrado na classe Veiculo. Para que as demais classes herdem estas características nós devemos utilizar a palavra reservada extends.

Então, as classes que definimos anteriormente, seriam reescritas da seguinte forma:

// Classe que representa o Jipe 

public class Jipe extends Veiculo{
   public void ligarTracao4x4()
   {
      //Código aqui
   }
}

// Classe que representa o Carro de passeio 

public class CarroPasseio extends Veiculo{
   public void ligarArCondicionado()
   {
      //Código aqui
   }
}

// Classe que representa o Utilitário 

public class Utilitario extends Veiculo {
   public void ligarFarolMilha()
   {
      //Código aqui
   }
}

Graficamente podemos representar esta hierarquia de classes da seguinte forma:





Nesta nova hierarquia de classes toda a subclasse de Veiculo irá compartilhar as suas características, dizemos que um jipe, carro de passeio ou utilitário são todos do tipo Veiculo. E da mesma forma toda a subclasse de Jipe irá herdar as características tanto de Veiculo quanto de Jipe.


Encapsulamento


Apesar do nome relativamente esquisito o conceito é simples. Encapsulamento refere-se ao isolamento entre as partes do programa. Uma das principais formas de fazer isso é proibindo o acesso direto as variáveis de um objeto por objetos externos.

Para isso, utilizamos os modificadores de acesso existentes em java. Estes modificadores funcionam da seguinte forma:
  • public: Qualquer objeto pode acessar o membro;
  • default: Qualquer objeto do mesmo pacote pode acessar o membro e subclasses de outros pacotes;
  • protected: O membro é acessível apenas por objetos do mesmo pacote;
  • private: O membro é acessível apenas internamente (próprio objeto);
Exemplo:

class Conta {  
          
    private double salario;  
    private String nome;
 
}

Um atributo privado só pode ser acessado ou alterado por código escrito dentro da classe na qual ele foi definido. Para acessá-los em outras partes do programa, utilizamos os métodos getters e setters.

  • Getters: Método que retorna o atributo.
  • Setters: Método que atribui/modifica o valor de um atributo.
Exemplo:

/* classe que demonstra o uso do get e set, como os atributos são do tipo
 * private, somente poderão ser acessados fora desta classe com o uso destes
 * métodos.
*/

class Conta {           
    private double salario;  
    private String nome;
 
    // Declarando os métodos Get e Set do atributo salario
 
    public double getSalario() {
       return salario;
    }
 
    public void setSalario(double salario) {
       this.salario = salario;
    }

    // Declarando os métodos Get e Set do atributo nome
 
    public String getNome() {
      return nome;
    }

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

A seguir, a classe AcessaConta mostra como é feito o acesso aos atributos do tipo private.

class AcessaConta {  
   public static void main(String[] args) {  
  
     Conta c = new Conta();
  
     // Chama o método set dos atributos nome e salario e altera os seus valores
     c.setNome("Oberdan Martins"); 
     c.setSalario(100);
  
     // Chama o método get dos atributos nome e salario e retorna os seus valores
     System.out.println(c.getNome());
     System.out.println(c.getSalario());
  
   }
}

Normalmente, os métodos são public (publicos) e os atributos private (privados), isto ocorre pois nós desejamos que os atributos de um objeto só possam ser alterados por ele mesmo, desta forma nós inviabilizamos situações imprevistas.

Orientação a Objetos


Orientação a objetos é uma maneira de programar que ajuda na organização e resolve muitos problemas enfrentados pela programação procedural.

Objetos:

Objetos são “coisas” que temos no mundo real e abstraímos no mundo virtual para que possamos manipulá-los na resolução de problemas. Um objeto no mundo real sempre possui estado e comportamento, isto é, ele possui características e ações que são pertinentes a sua natureza. Para clarificar nada melhor do que alguns exemplos:

Utilizando o exemplo do objeto Conta, vamos ver como é realizado a orientação a objetos em Java.

Classes:


Antes de um objeto ser criado, devemos definir quais serão os seus atributos e métodos. Essa definição é realizada através de uma classe.

-> Definindo os atributos:

 // Declarando uma classe com nome Conta e seus atributos
 
 class Conta {
    int numero;      // tipo int armazena números inteiros.
    double saldo;    // Tipo double armazena numeros com casas decimais
    double limite;
 }

-> Criando objetos:

Após definir a classe Conta, podemos criar objetos a partir dela. O comando para criar objetos é o new.
class OrientacaoObjetos {
    public static void main(String[] args) {
  
       new Conta();  // Criando um objeto

   }
}

Ao utilizar o comando new, um objeto é alocado em algumlugar da memória. Para que possamos acessar esse objeto, precisamos da referência dele. O comando new devolve a referência do objeto que foi criado.
Para guardar as referências devolvidas pelo comando new, devemos utilizar variáveis não primitivas.
Exemplo:

Conta referecia = new Conta();

Com a referência definida, podemos alterar ou acessar os valores guardados nos atributos de um objeto. A sintaxe para acessar um atributo utiliza o operador ".".

// Declarando uma classe com nome Conta e seus atributos

class Conta {
   int numero;      
   double saldo;   
   double limite;
}

// Classe que contém o método principal do programa

class OrientacaoObjetos {
   public static void main(String[] args) {
  
     Conta referencia = new Conta();  // Instancia um objeto
  
     referencia.numero = 1;
     referencia.saldo = 1000.0;
     referencia.limite = 500.0;
  
     // Imprime as informações na tela
  
     System.out.println(referencia.numero + "\n" +
                        referencia.saldo + "\n" + referencia.limite);

  }
}



Bom, no próximo artigo vamos falar um pouco sobre os métodos, então nos vemos lá...

Arrays

Um array é um objeto que armazena um número pré-definido de  elementos, isto é, o seu tamanho é definido no momento da sua construção. Seus  elementos são acessados através de índices que iniciam-se sempre por 0 (zero), ou  seja, um array de tamanho quatro terá índices 0, 1, 2 e 3.


Para conhecer o tamanho total de um array basta você acessar o atributo length. Este atributo retorna um valor inteiro (int) que indica qual a capacidade máxima de armazenamento deste array.

Lembretes:
  1. Primeira posição (índice): de qualquer array é sempre 0; 
  2. Última posição (índice): é sempre o seu tamanho - 1 (length - 1).

Exemplo simples de um Array:

public class Arrays {
 
    public static void main (String[] args) {
  
     int[] numeros = new int[] {23, 12, 55, 02, 07, 19}; //declarando um array
  
     for(int i = 0; i < numeros.length; i++) { //Percorrendo o array ate total
        System.out.print(numeros[i] + ", "); //exibindo os elementos do array
     }
   }
}

Se formos percorrer todos elementos de um array, podemos utilizar o for de uma outra forma. Veja:

/* Exemplo que soma todos os numeros de um array */

public class Arrays {

   public static void main(String[] args) {
  
     int[] numeros = {87, 68, 94, 100, 83, 78, 85, 91, 76, 87};
     int soma = 0;
  
     for (int numero : numeros) //comando for com uma sintaxe diferente
                                //ele percorre todo o array
       soma += numero; //Soma todos os elementos do array
    
       System.out.print("Soma total dos elementos: " + soma);
   }
}

Arrays Multidimensionais

Arrays multidimensionais são implementados como arrays dentro de arrays. São declarados ao atribuir um novo conjunto de colchetes depois do nome do array. Por exemplo:

// array inteiro de 512 x 128 elementos
int [][] two = new int[512][128];

Acessar um elemento em um array multidimensional é semelhante a acessar elementos em um array de uma dimensão. Por exemplo:

public class Arrays {

    public static void main (String[] args) {  

       String[][] contatos = {{"Layla" , "735-1234", "New York"} ,
                              {"Joyce" , "983-3333" , "Londres"} ,
                              {"Jenifer" , "456-3322", "Sidney"}};
     
       System.out.println("Nome: " + contatos[0][0]);
       System.out.println("Tel : " + contatos[0][1]);
       System.out.println("End : " + contatos[0][2] + "\n");
     
       System.out.println("Nome: " + contatos[1][0]);
       System.out.println("Tel : " + contatos[1][1]);
       System.out.println("End : " + contatos[1][2] + "\n");
     
       System.out.println("Nome: " + contatos[2][0]);
       System.out.println("Tel : " + contatos[2][1]);
       System.out.println("End : " + contatos[2][2]);
   }
}

Resultado do programa acima:

Nome: Layla
Tel    : 735-1234
End   : New York

Nome: Joyce
Tel    : 983-3333
End   : Londres

Nome: Jenifer
Tel    : 456-3322
End   : Sidney

É isso pessoal, espero que deu para esclarecer um pouco sobre este assunto. Qualquer dúvida é só postar um comentário aqui em baixo.

Entrada de dados

Como eu faço para ler algo que o usuário digita no teclado?

No Java existe uma classe chamada scanner que engloba diversos métodos para realizar este serviço.

Veja um exemplo:

import java.util.Scanner;

public class EntradaDeDados {

   public static void main(String[] args) {
  
      Scanner x = new Scanner(System.in);
      System.out.print("Digite seu nome: ");
      String nome = x.next();
      System.out.println("Bem vindo " + nome);
   }
}

Inicialmente, definimos a chamada ao pacote que contém a classe Scanner:

import java.util.Scanner;

Definimos uma variável, denominada x, que será criada a partir da classe Scanner e direcionada para a entrada padrão:

     Scanner x = new Scanner(System.in);

De forma semelhante, mostramos uma mensagem solicitando informação do usuário:

     System.out.print("Digite seu nome: "); 

Utilizamos a variável x para chamarmos o método que fará o recebimento dos dados digitados:

    String nome = x.next(); 

A classe Scanner possui diversos métodos que podem ser utilizados para realizar este serviço. Os principais métodos que podemos utilizar, neste caso, são:

String i = scanner.next() //Aguarda uma entrada em formato String 
int i = scanner.nextInt() //Aguarda uma entrada em formato Inteiro 
long i = scanner.nextLong() //Aguarda uma entrada em formato Inteiro Longo 
float i = scanner.nextFloat() //Aguarda uma entrada em formato Fracionário 
Double i = scanner.nextDouble() //Aguarda uma entrada em formato Fracionário 

Estruturas de controle de decisão

Estruturas de controle de decisão são instruções em linguagem Java que permitem que blocos específicos de código sejam escolhidos para serem executados, redirecionando determinadas partes do fluxo do programa. 

IF - ELSE

O comando if permite que valores booleanos sejam testados. Se o valor passado como parâmetro para o comando if for true(verdadeiro) o bloco do if é executado caso contrário o bloco do else é executado. O parâmetro passado para o comando if deve ser um valor booleano, caso contrário o código não compila. O comando else e o seu bloco são opcionais. 

Exemplo:

public class Controles {
   public static void main(String[] args) {
  
     int nota1 = 4;
     int nota2 = 3;
     int resultado = nota1 + nota2; 
  
     if (resultado > 6) { 
        System.out.print("Aluno aprovado");
     } else {
        System.out.print("Aluno reprovado");
     }
  
     //se resultado maior(>) que 6, aluno aprovado,
     //senao, aluno reprovado
   }
} 

WHILE

Através do comando while, é possível definir quantas vezes um determinado trecho de código deve ser executado pelo computador.

Exemplo:

/* Este codigo ira imprimir os numeros inteiros ate que 
 * x seja menor(<) que 10. A instrucao x++ funciona como 
 * um contador, ela vai incrementando o valor de x com  mais
 * um valor a cada execucao do codigo. Se essa linha for removida
 * o codigo ficara em uma repeticao infinita. */

public class Controles {
   public static void main(String[] args) {
 
     int x = 0;
  
     while (x < 10) {
        System.out.println(x);
        x++;
     }
   }
}

DO - WHILE

A declaração do-while é similar ao while. Ele executa a instrução pelo menos uma vez e continua executando enquanto a expressão booleana for verdadeira.


public class Controles {
   public static void main(String[] args) {
 
     int x = 0;
  
     // O do-while garante que pelo  menos uma vez o codigo seja executado
  
     do {
        System.out.println(x);
        x++;
     } while (x < 10);
   }
}

FOR

A declaração for, como nas declarações anteriores, permite a execução do mesmo código uma quantidade determinada de vezes. 

for possui três argumentos:

for (declaração_inicial; expressão_lógica; salto) { 
instrução1; 
instrução2; ... 
} 

onde:
declaração_inicial: inicializa uma variável para o laço
expressão_lógica: compara a variável do laço com um valor limite
salto: atualiza a variável do laço.

Exemplo:

/* Neste exemplo, uma variável i, do tipo int, é inicializada com o valor zero. A expressão lógica
"i é menor que 10" é avaliada. Se for verdadeira, então a instrução dentro do laço é
executada. Após isso, a expressão i terá seu valor adicionado em 1 e, novamente, a condição
lógica será avaliada. Este processo continuará até que a condição lógica tenha o valor falso. */

public class Controles {
   public static void main(String[] args) {
 
     for (int i = 0; i < 10; i++) {
        System.out.print("item: " + i);
     }
 }

Primeiro programa

Bom, vamos conhecer a sintaxe dos programas desenvolvidos em Java. Você pode utilizar dois métodos para escrever, compilar e rodar os programas, a primeira é por intermédio de uma console e um editor de texto e a segunda é utilizando uma IDE como NetBeans ou Eclipse (que será utilizado para escrever os programas de exemplo).

Continuando, apresento nosso primeiro programa, o clássico "Alô pessoal!". O objetivo deste programa é simplesmente escrever na tela a frase "Alô pessoal!". Vejamos como é o código fonte:

public class Hello {
     public static void main(String[] args) {
          System.out.println("Alo pessoal");
     }
}

  • Todo programa Java deve conter ao menos uma classe, e que é dentro de uma classe que vão os dados e os procedimentos.
  • O método main é o ponto onde se dá o início da execução do programa, isto é, um método chamado automaticamente pela JVM.
  • System.out.print é o nome de uma função que serve para escrever informações textuais na tela. Os dados a serem escritos, devem estar delimitados entre os parênteses "(" e ")". Pode ser:
    • print: escreve o dado e mantém o cursor na mesma linha.
    • println: escreve o dado e muda o cursor para próxima linha.
Ex: Mostra cada palavra em uma linha.

public class Hello {
     public static void main(String[] args) {
          System.out.println("Alo ");
          System.out.print("pessoal!");
     }
}

PARA PRATICAR!!!
  • Altere o  programa para que mostre a seguinte mensagem:

Bem vindo a programação 
Java [SeuNome]!!!


Conhecendo Java

UM POUCO DE HISTÓRIA:

Java é uma linguagem de programação orientada a objeto desenvolvida na década de 90 por uma equipe de programadores chefiada por James Gosling, na empresa Sun Microsystems.

A motivação original do Java era a necessidade de uma linguagem independente de plataforma que podia ser utilizada em vários produtos eletrônicos, tais como torradeiras e refrigeradores.
Ambientes de desenvolvimento:

É possível desenvolver aplicações em Java através de vários ambientes de desenvolvimento integrado (IDEs). Dentre as opções mais utilizadas pode-se destacar:
  • Eclipse — um projeto aberto iniciado pela IBM
  • JBuilder — um ambiente desenvolvido pela empresa Borland
  • NetBeans (software livre) — uma IDE desenvolvida pela Sun Microsystems
Extensões em Java:

  • J2ME (Micro-Edition) - É a plataforma Java para dispositivos compactos, como celulares, PDAs, controles remotos, e uma outra gama de dispositivos.
  • J2SE (Standard Edition) - É uma ferramenta de desenvolvimento para a plataforma Java. Ela contém todo o ambiente necessário para a criação e execução de aplicações Java, incluindo a máquina virtual Java (JVM), o compilador Java, as APIs do Java e outras ferramentas utilitárias para uma melhor funcionalidade.
  • JEE (Enterprise Edition) - Inclui toda a funcionalidade existente na plataforma Java SE mais todas as funcionalidades necessárias para o desenvolvimento e execução de aplicações em um ambiente corporativo. Fornecem funcionalidade para implementar software Java distribuído, tolerante a falhas e multi-camada, baseada amplamente em componentes modulares executando em um servidor de aplicações, além disso, contém bibliotecas desenvolvidas para o acesso a base de dados, RPC, CORBA, etc.

Se tiver um tempinho, assista a palestra realizada no Campus Party falando sobre Java e software livre:


Muito Obrigado pela atenção e continuaremos no próximo tópico!!!