Atualização dos tópicos de Java até aqui

Neste módulo veremos:

Entrada de dados do teclado

Este é um dos tópicos mais importantes na elaboração de nossos códigos para aprender e testar as características desta linguagem de programação. Veremos abaixo um pequeno código que exemplifica a entrada de dados via teclado.

/** LeSoma.java
 * apresenta API de leitura de teclado
 * @version 23.ago.2008
 */
import java.util.Scanner;

public class LeSoma {

    public static void main (String[] args) {
    int valor1, valor2, soma;
    String nome;
    Scanner entrada;

    entrada = new Scanner(System.in);
    System.out.print ("Entre o seu nome: ");
    nome = entrada.nextLine();

    System.out.print ("Entre um valor numerico interiro: ");
    valor1 = entrada.nextInt();
    System.out.print ("Entre mais um valor: ");
    valor2 = entrada.nextInt();

    soma = valor1+valor2;
    System.out.println(nome+" a soma dos valores eh: "+soma);
    }
}
/* fim LeSoma.java
 */

A plataforma Java disponibiliza um conjunto extenso de API (Application Program Interfaces). São várias API em vários tópicos, desde programação gráfica até recursos de comunicação e web. Cada API contém um conjunto de classes que visam facilitar a programação Java num determinado tópico. As classes na API podem ou não estarem agrupadas em packages, ou seja, pacotes de agrupamentos de classes.
Vejam a página Java JSE 6 API Reference.

A declaração import java.util.Scanner; importa a classe Scanner para poder ser utilizada no código atual.

Toda classe, para ser usada, precisa ser instanciada, e neste código entrada é uma referência ao objeto que irá ler os dados.

A classe System contém diversos atributos e métodos de comunicação e acessibilidade com o sistema operacional. Reparem que a classe System não pode ser instanciada. Ela descende de java.lang e que, por sua vez, descende de java.lang.Object, a classe maior de Java. Dentro de System existem os atributos dos streams de entrada e saída padrão e do fluxo de erros. Logo, o in é o standard input stream, neste caso, o teclado.

Ainda quanto a classe Scanner, reparem nos métodos nextInt() e nextLine() responsáveis pela leitura de um valor inteiro e de uma cadeia de caracteres. Esta classe é a responsável pelo parsing e separação dos tipos primitivos e strings. A classe Scanner tem a capacidade de quebrar os tokens de entrada usando delimitadores de padrão, a exemplo de expressões regulares.

Atributos

Os atributos de classe, ou em objetos, as variáveis de instância, correspondem aos campos que guardam os características das classes e dos objetos.

As palavras atributos e variáveis são usadas indistintamente na documentação da linguagem mas, o mais importantes aqui é definir os vários tipos de variáveis/atributos de Java. Veremos:

Consideração sobre atributos

No exemplo anterior poderíamos ficar tentados a colocar todas as variáveis locais de main() como variáveis de classe. Veja o que acontece se tentarmos alterar as declarações:

non-static variable xyz  cannot be referenced from a static context
Ou seja, a mensagem de erro diz que uma variável de instância (não-estática) não pode ser referenciada, chamada, a partir de um contexto estático, ou seja, de um método estático.

A explicação para esta mensagem de erro é simples: Como uma variável de instância, única para cada objeto, ou seja, podem existir várias instâncias dela, pode ser referenciada por um método único para todos os objetos? Como este método saberá qual variável de instância escolher?

Notem também que alterar esta variável para static certamente compromete a lógica do código pois é uma mudança conceitual relevante a transformação de uma variável de instância numa variável de classe.

Tipos primitivos de Java

Chamamos de tipos primitivos todos os tipos pré-definidos de uma linguagem. Java tem oito tipos primitivos, os quais veremos abaixo. Covém também lembrar que Java é uma linguagem fortemente tipada, ou seja, todas as suas variáveis tem que ter seu tipo declarado antes de serem usadas. Vejamos quais são os tipos primitivos de Java:

Os tipos primitivos, quando não inicializados, possuem um valor padrão default, que nos casos numérios é zero. Para caracter também é o equivalente a zero, ou seja, o valor \u0000. Lembramos que não convém deixar para a linguagem, ou para o compilador, a tarefa de inicialização de valores. Isto não é considerado uma boa prática de programação.

O tipo por referência

Diferente dos tipos primitivos, o que chamamos de tipos por referência, ou somente referência são as variáveis que armazenam as localizações de objetos. Por isso, diz-se que referenciam objetos do programa. Estas variáveis de referência são inicializadas com o tipo null por default. As referências são usadas para invocar os objetos, ou seja, chamar os objetos.

O tipo String

Apesar de já utilizado aqui, este tipo não é um tipo primitivo da linguagem Java. String é uma classe declarada em java.lang.String. Pela alocação desta classe na hierarquia de classes de Java, logo dentro da linguagem, vemos a distinção que este tipo recebe e talvez por isso alguns chegam a pensar que este é um tipo primitivo. As cadeias de caracteres são imutáveis uma vez declaradas, como em String cadeia = "uma cadeia de caracteres".

Arranjos ou vetores

Um arranjo em Java é um artifício de programação capaz de armazenar uma quantidade fixa de objetos, ou seja, depois de criado seu tamanho é inalterável.

O segmento de código abaixo exemplifica a criação de um arranjo de inteiros:

  int[] anArray;  //declara um arranjo de inteiros

  anArray = new int[10];  //aloca memoria para 10 inteiros
            
  anArray[0] = 10; //inicializa o primeiro elemento
  anArray[1] = 20;

Notem que o arranjo pode ser declarado mas não precisa ser inicializado, nem criado no momento da sua declaração. A criação do arranjo ocorre pelo mecanismo de instanciação, o que demonstra que um arranjo é um recipiente de objetos.

Notem também que a formalização do arranjo através dos colchetes ocorre diferente da linguagem C. Em Java os colchetes sucedem a declaração de tipo, ou seja, em Java declaramos o tipo arranjo e não um arranjo de tipos.

Módulos para programas em Java

Existem 3 tipos de módulos em Java, são eles

Veremos agora alguns detalhes sobre métodos, classes e pacotes, além de mais conceitos de orientação a objetos, baseados na classe Math.

Métodos static, campos static e a classe Math

java.lang.Object
  |
  --- java.lang.Math

Como sabemos, os métodos de uma classe são invocados através dos objetos instanciados por estas classes. Dada a declaração de um objeto, por exemplo meuObj = new MeuObj(), invocamos um método chamando-os como, por exemplo, meuObj.metodoUm().

Muito embora a maioria dos métodos seja invocadada a partir de objetos, nem sempre este é o caso pois alguns métodos podem realizar atividades que não dependem do conteúdo do objeto muito menos da situação (do estado) de seus atributos. Ainda assim, muitas vezes um mesmo objeto, ou um mesmo método, pode ser o suficiente para todas as situações. Métodos declarados para serem utilizados sem a instanciação de um objeto, são declarados usando-se o qualificador static. Se assim declarados, são conhecidos como métodos de classe. Todos os métodos da classe Math são static. Visitem a classe Math clicando aqui.

Observe como usar um método da classe Math

  double raiz;
  raiz = Math.sqrt(900.0);

Notem que, como não existe a instanciação da classe, a classe deve ser usada para invocar o método, ou seja, são invocados via o nome da classe.

Além dos métodos static, a classe Math também declara dois campos static, Math.PI e Math.E. Torná-los static significa que eles só podem se acessados através de sua classe. Para que tenham visibilidade e acessibilidade, estes valores também são declarados como public e, para serem considerados como constantes, ou seja, para não serem modificáveis, foram também declarados como final. Assim, as declarações destas variáveis de classe são public static final.

Aplicando os conceitos com o jogo Craps

Craps é um jogo de azar em que se usa dados. As regras são simples: O jogador lança dois dados e a soma das faces é calculada. O jogador ganha se a soma for 7 ou 11. Se a soma for 2, 3 ou 12, o jogador perde. Caso a soma seja 4, 5, 6, 8, 9 ou 10 no seu primeiro lance, esta será a sua pontuação. Para ganhar, voce deve continuar a jogar até conseguir a sua pontuação.

Vejamos a implementação deste jogo segundo Deitel e Deitel

/** Craps.java
 */
import java.util.Random;

public class Craps {

    private Random alea = new Random();
    private enum Status {CONTINUA, VENCEU, PERDEU};

    private final static int DOIS=2;
    private final static int TRES=3;
    private final static int SETE=7;
    private final static int ONZE=11;
    private final static int DOZE=12;

    public void play() {
	int meusPontos =0;
	Status jogoStatus;

	int somaDados = rolaDado(); //primeira vez
	switch (somaDados) {
	case SETE:  //ganha
	case ONZE:  //ganha
	    jogoStatus = Status.VENCEU;
	    break;

	case DOIS:  //perde
	case TRES:
	case DOZE:
	    jogoStatus = Status.PERDEU;
	    break;

	default:  //proxima jogada pode definir
	    jogoStatus = Status.CONTINUA;
	    meusPontos = somaDados;
	    System.out.println ("Soma: "+meusPontos);
	    break;
	}

	while (jogoStatus == Status.CONTINUA) {
	    somaDados = rolaDado(); //segunda vez

	    if (somaDados == meusPontos) //ganha por pontuacao
		jogoStatus = Status.VENCEU;
	    else
		if (somaDados == SETE)  //7 antes da pontuacao
		    jogoStatus = Status.PERDEU;
	}

	if (jogoStatus == Status.VENCEU)
	    System.out.println ("Venceu!");
	if (jogoStatus == Status.PERDEU)
	    System.out.println ("Voce perdeu!");
    }//play()

    public int rolaDado() {
	int dado1 = 1 + alea.nextInt(6);
	int dado2 = 1 + alea.nextInt(6);
	int soma = dado1+dado2;

	System.out.printf ("Jogados %d e %d = %d\n", dado1, dado2, soma);
	return soma;
    }//rolaDado()

}//Craps

E agora o classe para teste

/** CrapsTest
 */
public class CrapsTest {
    public static void main (String args[]) {
	Craps jogo = new Craps();
	jogo.play();
    }
}

Um possível resultado da execução deste jogo seria

$ java CrapsTest
Jogados 1 e 4 = 5
Soma: 5
Jogados 4 e 5 = 9
Jogados 1 e 2 = 3
Jogados 3 e 3 = 6
Jogados 1 e 2 = 3
Jogados 6 e 4 = 10
Jogados 6 e 6 = 12
Jogados 6 e 2 = 8
Jogados 6 e 2 = 8
Jogados 3 e 2 = 5
Venceu!

E assim vimos alguns dos conceitos importantes tanto de Java quanto de POO.

Exercícios

  1. Faça modificações nas classes Craps e na sua classe executora para realizar 100 jogadas de Craps e verificar qual a taxa de vitória neste jogo.
  2. Teste a utilização de alguns métodos da classe Math e tambebém de seus campos PI e E.
Última modificação feita em: 27 de agosto de 2008
Evandro Eduardo Seron Ruiz, PhD (evandro at usp ponto br)
www.imagcom.org/evandro/