(Parte 5 de 5)

Um método sempre tem que retornar alguma coisa, nem que essa coisa seja nada, como nos exemplos anteriores onde estávamos usando o void.

Um método pode retornar um valor para o código que o chamou. No caso do nosso método saca podemos devolver um valor booleano indicando se a operação foi bem sucedida.

Capítulo 4 - Orientação a objetos básica - Métodos com retorno - Página 3

Material do Treinamento Java e Orientação a Objetos

2 //outros metodos e atributos ...

Agora a declaração do método mudou! O método saca não tem void na frente, isto quer dizer que, quando é acessado, ele devolve algum tipo de informação. No caso, um boolean. A palavra chave return indica que o método vai terminar ali, retornando tal informação.

Exemplo de uso:

System.out.println("Não consegui sacar"); }

Ou então, posso eliminar a variável temporária, se desejado:

Mais adiante, veremos que algumas vezes é mais interessante lançar uma exceção (exception) nesses casos.

Meu programa pode manter na memória não apenas uma conta, como mais de uma:

1 class TestaDuasContas { 2 public static void main(String[] args) { 3 4 Conta minhaConta; 5 minhaConta = new Conta();

Capítulo 4 - Orientação a objetos básica - Métodos com retorno - Página 34

Material do Treinamento Java e Orientação a Objetos

4.7 - Objetos são acessados por referências

Quando declaramos uma variável para associar a um objeto, na verdade, essa variável não guarda o objeto, e sim uma maneira de acessá-lo, chamada de referência.

É por esse motivo que, diferente dos tipos primitivos como int e long, precisamos dar new depois de declarada a variável:

1 public static void main(String args[]) { 2 Conta c1; 3 c1 = new Conta(); 4 5 Conta c2; 6 c2 = new Conta(); 7 }

O correto aqui, é dizer que c1 se refere a um objeto. Não é correto dizer que c1 é um objeto, pois c1 é uma variável referência, apesar de, depois de um tempo, os programadores java falem “Tenho um objeto c do tipo Conta”, mas apenas para encurtar a frase “Tenho uma referência c a um objeto do tipo Conta”.

Basta lembrar que, em java, uma variável nunca é um objeto. Não há, no java, uma maneira de criarmos o que é conhecido como “objeto pilha” ou “objeto local”, pois todo objeto em java, sem exceção, é acessado por uma variável referência.

Esse código nos deixa na seguinte situação:

Conta c1; c1 = new Conta();

Conta c2; c2 = new Conta();

Capítulo 4 - Orientação a objetos básica - Objetos são acessados por referências - Página 35

Material do Treinamento Java e Orientação a Objetos

Internamente, c1 e c2 vão guardar um número que identifica em que posição da memória aquela Conta se encontra. Dessa maneira, ao utilizarmos o “.” para navegar, o java vai acessar a Conta que se encontra naquela posição de memória, e não uma outra.

Para quem conhece, é parecido com um ponteiro, porém você não pode manipulá-lo e utilizá-lo para guardar outras coisas.

Agora vamos a um outro exemplo:

Qual é o resultado do código acima? O que aparece ao rodar?

O que acontece aqui? O operador = copia o valor de uma variável. Mas qual é o valor da variável c1? É o objeto? Não. Na verdade, o valor guardado é a referência (endereço) de onde o objeto se encontra na memória principal.

Na memória, o que acontece nesse caso:

Conta c1 = new Conta(); Conta c2 = c1;

Quando fizemos c2 = c1, c2 passa a fazer referência para o mesmo objeto que c1 referencia nesse instante.

Então, nesse código em específico, quando utilizamos c1 ou c2 estamos nos referindo exatamente ao mesmo objeto! Elas são duas referências distintas, porém apontam para o mesmo objeto! Compará-las com “==” irá nos retornar true, pois o valor que elas carregam é o mesmo!

Outra forma de perceber, é que demos apenas um new, então só pode haver um objeto Conta na memória.

Atenção: não estamos discutindo aqui a utilidade de fazer uma referência apontar pro mesmo objeto que outra. Essa utilidade ficará mais clara quando passarmos variáveis do tipo referência como argumento para métodos.

Capítulo 4 - Orientação a objetos básica - Objetos são acessados por referências - Página 36

Material do Treinamento Java e Orientação a Objetos

new

O que exatamente faz o new? O new executa uma série de tarefas, que veremos mais adiante. Mas, para melhor entender as referências no Java, saiba que o new, depois de alocar a memória para esse objeto, devolve uma “flecha”, isto é, um valor de referência. Quando você atribui isso a uma variável, essa variável passa a se referir para esse mesmo objeto.

Podemos então ver outra situação:

O operador == compara o conteúdo das variáveis, mas essas variáveis não guardam o objeto, e sim o endereço em que ele se encontra. Como em cada uma dessas variáveis guardamos duas contas criadas diferentemente, eles estão em espaços diferentes da memória, o que faz o teste no if valer false. As contas podem ser equivalentes no nosso critério de igualdade, porém elas não são o mesmo objeto. Quando se trata de objetos, pode ficar mais fácil pensar que o == compara se os objetos (referências, na verdade) são o mesmo, e não se são iguais.

Para saber se dois objetos têm o mesmo conteúdo, você precisa comparar atributo por atributo. Veremos uma solução mais elegante para isso também.

4.8 - O método transfere()

E se quisermos ter um método que transfere dinheiro entre duas contas? Podemos ficar tentados a criar um método que recebe dois parâmetros: conta1 e conta2 do tipo Conta. Mas cuidado: assim estamos pensando de maneira procedural.

Capítulo 4 - Orientação a objetos básica - O método transfere() - Página 37

Material do Treinamento Java e Orientação a Objetos

A idéia é que, quando chamarmos o método transfere, já teremos um objeto do tipo Conta (o this), portanto o método recebe apenas um parâmetro do tipo Conta, a Conta destino (além do valor):

class Conta {

// atributos e metodos...

void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor; }

Para deixar o código mais robusto, poderíamos verificar se a conta possui a quantidade a ser transferida disponível. Para ficar ainda mais interessante, você pode chamar os métodos deposita e saca já existentes para fazer essa tarefa:

class Conta {

// atributos e metodos...

boolean transfere(Conta destino, double valor) { boolean retirou = this.saca(valor); if (retirou == false) { // não deu pra sacar! return false; } else { destino.deposita(valor); return true; }

Capítulo 4 - Orientação a objetos básica - O método transfere() - Página 38

Material do Treinamento Java e Orientação a Objetos

Quando passamos uma Conta como argumento, o que será que acontece na memória? Será que o objeto é clonado?

No java, a passagem de parâmetro funciona como uma simples atribuição como no uso do “=”. Então, esse parâmetro vai copiar o valor da variável do tipo Conta que for passado como argumento. E qual é o valor de uma variável dessas? Seu valor é um endereço, uma referência, nunca um objeto. Por isso não há cópia de objetos aqui.

Esse útltimo código poderia ser escrito com uma sintaxe muito mais sucinta. Como?

Transfere Para

Perceba que o nome deste método poderia ser transferePara ao invés de só transfere. A chamada do método fica muito mais natural, é possível ler a frase em português que ela tem um sentido:

conta1.transferePara(conta2, 50); A leitura deste código seria “Conta1 transfere para conta2 50 reais”.

4.9 - Continuando com atributos

As variáveis do tipo atributo, diferentemente das variáveis temporárias (declaradas dentro de um método), recebem um valor padrão. No caso numérico, valem 0, no caso de boolean, valem false.

Você também pode dar valores default, como segue:

Nesse caso, quando você criar um carro, seus atributos já estão “populados” com esses valores colocados.

cliente dono da conta. Começaríamos a ter muitos atributose, se você pensar direito, uma Conta não tem

Imagine que, agora, começamos a aumentar nossa classe Conta e adicionar nome, sobrenome e cpf do nome, nem sobrenome nem cpf, quem tem esses atributos é um Cliente. Então podemos criar uma nova classe e fazer uma composição

Seus atributos também podem ser referências para outras classes. Suponha a seguinte classe Cliente:

1 class Cliente { 2 String nome; 3 String sobrenome; 4 String cpf; 5 }

1 class Conta { 2 int numero; 3 double saldo; 4 double limite;

Capítulo 4 - Orientação a objetos básica - Continuando com atributos - Página 39

(Parte 5 de 5)

Comentários