Neste módulo veremos:
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.
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:
static
antes do tipo. Este qualificador diz que somente existirá uma cópia
daquela variável não importa quantas instanciações a classe tiver
tido. Por exemplo, uma variável especificando o número de rodas
de um objeto automóvel pode ser única para todos os objetos instanciados
de uma classe automóvel, já que provavelmente só existirão automóveis
com quatro rodas;
main (String[] args)
.
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 contextOu 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.
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:
int
é um tipo de 32 bits, ou seja, pode armazenar valores no domínio
-2.147.483.648 até 2.147.483.647 (inclusive);
true
ou false
. Não existe
uma definição precisa quanto ao espaço ocupado por este tipo na memória
RAM;
\u0000
até \uffff
.
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.
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.
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"
.
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.
Existem 3 tipos de módulos em Java, são eles
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.
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
.
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.
Craps
e na sua
classe executora para realizar 100 jogadas de Craps e verificar
qual a taxa de vitória neste jogo.
Math
e tambebém de seus campos PI e E.
(evandro at usp ponto br)