Na aula passada aprendemos que
● Podemos restringir o acesso aos atributos e métodos das classes utilizando modificadores de acesso - public,
private e protected
● Por padrão os atributos de uma classe são private e o acesso à leitura e escrita dos atributos deve ser ser feita através de métodos getters e setters
● Podemos definir métodos construtores para serem chamados no momento da instanciação dos objetos
Exercício pendente da aula passada
Na classe ContaBancaria descrita no próximo slide:
● coloque todos os seus atributos como privados e métodos como públicos
● para cada atributo crie seus métodos get e set
● crie um método construtor que receba como parâmetro o atributo numero
● crie duas instâncias com estados diferentes e depois utilize os métodos setters para modificar seus estados e os métodos getter para imprimir na tela os novos estados
Código da classe ContaBancaria
4
public class ContaBancaria { int numero;
double saldo;
void deposito(double deposito) {
this.saldo = this.saldo + deposito; }
String saque(double saque) { String resultado = ""; if(this.saldo > saque) {
this.saldo = this.saldo - saque; resultado = "sucesso"; }else { resultado = "fracasso"; } return resultado; } }
Hoje vamos aprender a resposta às seguintes
perguntas
Como comparar dois objetos do mesmo tipo?
Como eu imprimo na tela uma descrição textual do estado de um objeto?
Classe Carro
public class Carro {
private String placa;
public Carro(String placa) { this.placa = placa;
}
public String getPlaca() { return placa;
}
public void setPlaca(String placa) { this.placa = placa;
} }
Como saber se dois objetos do tipo carro são
iguais?
carro carro2
placa placa
O que o código abaixo imprime na tela?
Carro carro = new Carro("OYM8876"); Carro carro2 = new Carro("OYM8876"); if(carro == carro2) {
System.out.println("Os carros são iguais"); }else {
System.out.println("Os carros são diferentes"); }
O que o código abaixo imprime na tela?
Carro carro = new Carro("OYM8876"); Carro carro2 = new Carro("OYM8876"); if(carro == carro2) {
System.out.println("Os carros são iguais"); }else {
System.out.println("Os carros são diferentes");
}
A execução vai imprimir a mensagem do else
Por que?
● Quando inicializamos variáveis de tipos primitivos (int, char, boolean, etc), guardamos o valor da atribuição, por isso o operador de igualdade funciona (==)
● Já quando instanciamos objetos, guardamos a referência do objeto na atribuição (a localização do objeto na
memória do computador)
● Como os objetos desse exemplo de código tem referências distintas, eles serão diferentes
Variável primitiva vs. variável de referência
int a = 5;
Carro carro = new Carro("OYM8876");
5 B1 "OYM8876" variável primitiva int a referência de objeto da variável carro objeto armazenado no endereço B1
Cada objeto tem uma referência diferente
13 Carro carro = new Carro("OYM8876");
Carro carro2 = new Carro("OYM8876");
B7 B1 "OYM8876" referência de objeto da variável carro referência de objeto da variável carro2 objeto armazenado no endereço B1 "OYM8876" objeto armazenado no endereço B7
Logo, estamos comparando referências diferentes
no código abaixo
Carro carro = new Carro("OYM8876"); Carro carro2 = new Carro("OYM8876"); if(carro == carro2) {
System.out.println("Os carros são iguais"); }else {
System.out.println("Os carros são diferentes"); }
E o que acontece quando atribuímos uma referência
do objeto a outra variável?
Carro carro = new Carro ("ABC1234"); Carro carro2 = carro;
carro2.setPlaca("DEF5678");
E o que acontece quando atribuímos uma referência
do objeto a outra variável?
Carro carro = new Carro ("ABC1234"); Carro carro2 = carro;
carro2.setPlaca("DEF5678");
System.out.println(carro.getPlaca());
A execução vai imprimir “DEF5678”
Na prática
B7 carro
"ABC1234" Carro carro = new Carro ("ABC1234");
Na prática
B7 carro
"ABC1234" Carro carro = new Carro ("ABC1234"); Carro carro2 = carro
Na prática
B7 carro
"DEF5678" Carro carro = new Carro ("ABC1234"); Carro carro2 = carro
carro2.setPlaca("DEF5678");
Mas… voltando a nossa pergunta inicial… como
fazemo pra comparar dois objetos se já vimos
Precisamos criar um método que compare os
atributos dos objetos para saber se os atributos
Esse método é chamado equals
boolean objeto
Método equals da classe Carro
public boolean equals(Carro carro) { boolean iguais = false;
if(this.placa.equals(carro.getPlaca())) { iguais = true;
}
return iguais; }
Facilitando a leitura
public boolean equals(Carro carro) { boolean iguais = false;
String minhaPlaca = this.placa;
String outraPlaca = carro.getPlaca(); if(minhaPlaca.equals(outraPlaca)) {
iguais = true; }
return iguais; }
E agora é só chamar o método equals
25 Carro carro = new Carro("OYM8876");
Carro carro2 = new Carro("OYM8876"); if(carro.equals(carro2)) {
System.out.println("Os carros são iguais"); }else {
System.out.println("Os carros são diferentes");
}
A execução vai imprimir “Os carros são iguais”
Exercício
Como eu imprimo na tela uma descrição textual do estado de um objeto?
Muitas vezes precisamos de um relatório do estado
de um objeto
Carro carro = new Carro("OYM8876"); System.out.println(carro.getPlaca());
Podemos facilitar esse processo através do método
toString
public String toString() {
String resultado = this.placa; return resultado;
E aí chamamos o método toString onde precisarmos
Carro carro = new Carro("OYM8876"); System.out.println(carro.toString());
Exercício
O que é escopo?
● Região do programa onde a variável tem validade, ou seja, onde ela podemos acessar e/ou escrever nela ● É possível declarar variáveis com o mesmo nome
Em Java existem 4 níveis de escopo
● Variáveis estáticas ● Variáveis de instância
● Variáveis locais ou de métodos ● Variáveis de bloco
Variáveis estáticas ou de classe
● Pertencem a classe e existem independentemente de qualquer instância criada para a classe
● Permanecem válida durante toda a execução do programa
● Seu valor será o mesmo para todo os objetos instanciados daquela mesma classe
● Para criar uma variável ou método estático usa-se a palavra reservada static
Quando usar variáveis static em Java?
● Imaginem que vamos usar nossa classe Carro para
implementar o sistema de vendas de uma concessionária ● Queremos saber quantos carros foram vendidos ao todo ● Podemos usar uma variável estática como atributo da
Modificando a classe Carro
37
public class Carro {
private String placa;
public static int carrosVendidos; public Carro(String placa) {
this.placa = placa; carrosVendidos++; }
public String getPlaca() { return placa;
}
public void setPlaca(String placa) { this.placa = placa;
} }
Alterando o valor da variável carrosVendidos
public static void main(String[] args) { Carro carro = new Carro("OIM1234"); Carro carro2 = new Carro ("YEW8907"); System.out.println("Foram vendidos " + Carro.carrosVendidos + " carros.");
Na memória do computador
carro carro2 placa placa “OYM8876” “OYM8876” carrosVendidos 2Variáveis de instância
● São os atributos da classe
● São criada quando uma nova instância da classe é iniciada e pode ser referenciada enquanto aquela instância existir
● Por exemplo, o atributo placa da classe Carro, ou os atributos numerro e saldo da classe ContaBancaria
Variáveis locais
● Variáveis definidas dentro de métodos
● Tem escopo local durante a execução daquele método e não podem ser referenciadas em outros trechos do
programa
● É possível declarar variáveis com o mesmo nome em métodos diferentes
Exemplo
public int m(){ int a = 0; return a + 1; } public void p(){ a = 8; } ERRO! A variável a só existe nométodo onde foi declarada
Exemplo 2
public class Teste { private int a; public int m(){ int a = 0; return a + 1; } public void p(){ a = 8; } } variável local variável de instância
Variáveis de bloco
Permanecem ativas enquanto o bloco for executado
int a = 1; for(int b = 0; b < 3; b++){ int c = 1; System.out.println(c); System.out.println(b); } a = c; ERRO! A variável c só existe dentro do bloco do for
Variáveis de bloco
Permanecem ativas enquanto o bloco for executado
int a = 1; if (a > 0) { int c = 2; } a = c; ERRO! A variável c só existe dentro do bloco do if
Por que o código abaixo não funciona?
public int test1(){
for(int i = 0; i < 10; i++){ if(Math.sqrt(i) > 2.5){ break; } } return i; }
Por que o código abaixo não funciona?
public void test3() { int c = 1; if(c > 3){ int a = 2; } c = c + a; }
Em resumo, vimos hoje
● Método equals e como variáveis primitivas e de referência são armazenadas na memória
● Método toString
● Escopo de variáveis