Buscar

PC2 Aula03

Prévia do material em texto

© ELFS 47 
•  Como já sabemos, a primeira preocupação na POO deve ser identificar as 
classes que o programa precisa. 
•  Em seguida, devemos pensar quais devem ser os campos e os métodos 
dessas classes (e, consequentemente, de seus objetos). 
•  Vamos imaginar que um programa precisa tratar com datas (dia/mes/ano) e 
que para esse programa foi construída a seguinte classe: 
3. Projeto de Classes: Campos e Métodos 
Data 
− int dia 
− int mes 
− int ano 
+ Data() 
+ Data(int, int, int) 
+ void paraFrente(int) 
+ void paraTras(int) 
+ String toString() 
− boolean anoBissexto() 
− int diasDoMes() 
− void avancar() 
− void voltar() 
Algumas questões importantes são: 
•  Por que os campos da classe são privados? 
•  Uma classe pode ter campos públicos? 
•  Por que alguns métodos são privados e outros 
são públicos? 
•  Por que o método Data() não tem um tipo, 
como os demais métodos? 
•  Por que existem dois métodos Data()? 
© ELFS 48 
•  Por que os campos são privados? Uma classe pode ter campos públicos? 
•  Os campos devem ser privados para garantir que o estado de um objeto seja 
sempre consistente. Uma classe pode ter campos públicos, desde que não 
seja possível atribuir novos valores a esses campos (caso das constantes). 
3. Projeto de Classes: Campos e Métodos 
d.dia = 32; // impossível 
Data 
+ int dia 
+ int mes 
+ int ano 
d.dia = 32; // problema 
Data 
− int dia 
− int mes 
− int ano 
Com os campos privados o 
usuário não pode atribuir um 
valor (válido ou inválido) a um 
campo. 
Se for necessário atribuir um 
valor a um campo, esta 
atribuição deve ser feita por 
um método público da classe. 
Isso garante que a atribuição 
será sempre válida. 
public void setDia(int d) 
{ 
 if (d >= 1 && d <= diasDoMes()) dia = d; 
 else System.out.println("Dia incorreto"); 
} 
© ELFS 49 
•  Os métodos públicos que atribuem valores aos campos privados da classe 
são conhecidos como setters. Esses métodos costumam ser declarados 
sempre como: 
setNomeDoCampo(tipo parâmetro) 
•  Classe Data: 
3. Projeto de Classes: Campos e Métodos 
Data 
− int dia 
− int mes 
− int ano 
public void setDia(int d) 
{ 
 if (d >= 1 && d <= diasDoMes()) dia = d; 
 else System.out.println("Dia incorreto"); 
} 
 
public void setMes(int m) 
{ 
 if (m >= 1 && m <= 12) mes = m; 
 else System.out.println("Mes incorreto"); 
} 
 
public void setAno(int a) 
{ 
 if (a >= 1) ano = a; 
 else System.out.println("Ano incorreto"); 
} 
+ void setDia() 
+ void setMes() 
+ void setAno() 
© ELFS 50 
•  Uma classe deve também incluir métodos públicos que retornam os valores 
atuais dos campos privados da classe. Esses métodos são conhecidos como 
getters e costumam ser declarados como: 
 
tipo getNomeDoCampo() 
•  Classe Data: 
3. Projeto de Classes: Campos e Métodos 
Data 
− int dia 
− int mes 
− int ano 
public int getDia() 
{ 
 return dia; 
} 
 
public int getMes() 
{ 
 return mes; 
} 
 
public int getAno() 
{ 
 return ano; 
} 
+ void setDia() 
+ void setMes() 
+ void setAno() 
+ int getDia() 
+ int getMes() 
+ int getAno() 
Observar que os getters 
garantem o acesso aos 
valores dos campos, uma 
vez que o acesso 
diretamente a um campo 
privado não é possível. 
d = dia; ERRADO! 
d = getDia(); CERTO! 
© ELFS 51 
•  Por que alguns métodos são privados e outros são públicos? 
•  Uma classe pode ter campos e métodos privados ou públicos. 
•  Campos: devem ser privados (para garantir a consistência dos objetos). 
•  Campos públicos: no caso de constantes (valor não pode ser alterado). 
•  Métodos: em geral, devem ser públicos (API da classe) 
•  Métodos privados: quando são internos à classe (não estão na API) 
•  Em geral, os campos e métodos de uma classe podem ser: 
 onde (package) indica que nenhum modificador foi usado. 
3. Projeto de Classes: Campos e Métodos 
Nível de acesso 
Modificador Classe Pacote Subclasse Todas 
public S S S S 
protected S S S N 
(package) S S N N 
private S N N N 
© ELFS 52 
•  Por que o método Data() não tem um tipo, como os demais métodos? E por 
que existem dois métodos Data()? 
•  Porque, para a classe Data, o método Data() é um construtor. O objetivo de 
um método construtor é construir objetos da classe. 
•  Os construtores são métodos especiais que têm o mesmo nome da classe e 
garantem que cada objeto da classe inicia sua existência em um estado 
consistente. 
•  Construtores, como qualquer outro método, podem receber parâmetros. 
•  Um construtor não retorna valor algum, nem mesmo do tipo void. 
•  Toda classe deve ter um construtor. Se nenhum construtor for declarado no 
corpo da classe, um construtor padrão será incluído na compilação. Este 
construtor padrão não tem parâmetros e permite que se criem objetos de 
uma classe utilizando a instrução new Classe(). 
•  Se em uma classe que não tinha um construtor explícito, for declarado um 
construtor, essa classe irá perder o construtor padrão. Se o construtor 
incluído tiver parâmetros, todas as chamadas posteriores a new Classe() 
causarão erros de compilação. Portanto, ao definir construtores em uma 
classe, deve-se sempre definir também um construtor sem parâmetros. 
3. Projeto de Classes: Campos e Métodos 
•  Exemplo. Vamos considerar a representação de um horário utiliza 3 campos 
inteiros: hor, min e seg. 
 
public class Horario 
{ 
 private int hor; 
 private int min; 
 private int seg; 
 
 public Horario() 
 { 
 setHora(0); 
 setMinuto(0); 
 setSegundo(0); 
 } 
 
 public Horario(int h, int m, int s) 
 { 
 setHora(h); 
 setMinuto(m); 
 setSegundo(s); 
 } 
 
 
© ELFS 53 
3. Projeto de Classes: Campos e Métodos 
Horario.java 
Uma classe pode ter mais 
de um construtor. 
 
Os construtores devem 
chamar os setters para 
atribuir valores aos 
campos da classe. 
 public int getHora() 
 { 
 return hor; 
 } 
 public int getMinuto() 
 { 
 return min; 
 } 
 public int getSegundo() 
 { 
 return seg; 
 } 
 
 public final void setHora(int h) 
 { 
 hor = (( h >= 0 && h < 24 )? h : 0); 
 } 
 public final void setMinuto(int m) 
 { 
 min = (( m >= 0 && m < 60 )? m : 0); 
 } 
 public final void setSegundo(int s) 
 { 
 seg = (( s >= 0 && s < 60 )? s : 0); 
 } 
© ELFS 54 
3. Projeto de Classes: Campos e Métodos 
Esses são os 
setters da classe. 
Observar que os 
setters devem ser 
sempre final void. 
Esses são os 
getters da classe. 
Observar que os 
getters são 
métodos que têm 
o mesmo tipo que 
o campo da classe 
a que se referem. 
© ELFS 55 
 @Override 
 public String toString() 
 { 
 DecimalFormat df = new DecimalFormat("00"); 
 return (df.format(getHora()) + ":" + 
 df.format(getMinuto()) + ":" + df.format(getSegundo())); 
 } 
} 
3. Projeto de Classes: Campos e Métodos 
© ELFS 55 
public class UsaHorario 
{ 
 public static void main(String[] args) 
 { 
 Horario h = new Horario(); 
 System.out.println(h.toString()); 
 h.setHora(15); 
 h.setMinuto(30); 
 System.out.println(h); 
 h = new Horario(20,60,99); 
 System.out.println(h); 
 } 
} 
UsaHorario.java 
Note que o método toString() 
pode ficar implícito. 
© ELFS 56 
•  A classe UsaHorario utiliza a classe Horario. Ou 
seja, a classe UsaHorario é um usuário da classe 
Horario. 
 
•  Os usuários de uma classe utilizam a parte pública da 
classe (a API da classe) e desconhecem como os 
campos e os métodos da classe foram implementados. 
•  Exemplo: se, em vez de representar um horário por 
três valores inteiros (hor, min, seg), um horário for 
representado como o número de segundosdesde a 
zero-hora, os usuários poderiam utilizar os mesmos 
métodos públicos e obter os mesmos resultados sem 
se dar conta disso. É claro que os métodos teriam que 
ser reimplementados, considerando essa nova 
representação do horário. 
w  
•  Se a implementação de uma classe é alterada, desde 
que a API da classe permaneça a mesma, o código-
fonte dos usuários da classe não precisa ser 
alterado. Isso torna muito mais fácil modificar e 
distribuir sistemas. 
3. Projeto de Classes: Campos e Métodos 
Horario 
− int hor 
− int min 
− int seg 
+ Horario() 
+ Horario(int h, int m, int s) 
+ int getHora() 
+ int getMinuto() 
+ int getSegundo() 
+ final void setHora() 
+ final void setMinuto() 
+ final void setSegundo() 
+ String toString() 
© ELFS 57 
Exemplo: 
3. Projeto de Classes: Campos e Métodos 
public class Horario 
{ 
 private int tempo; 
 
 public Horario() 
 { 
 setHora(0); 
 setMinuto(0); 
 setSegundo(0); 
 } 
 
 public Horario(int h, int m, int s) 
 { 
 setHora(h); 
 setMinuto(m); 
 setSegundo(s); 
 } 
 
 
Horario.java 
Até aqui nada mudou, pois os 
construtores chamam os setters 
para atribuir o valor correto ao 
campo da classe. 
© ELFS 58 
3. Projeto de Classes: Campos e Métodos 
 public int getHora() 
 { 
 return (tempo/3600); 
 } 
 public int getMinuto() 
 { 
 return ((tempo - 3600*getHora())/60); 
 } 
 public int getSegundo() 
 { 
 return (tempo - 3600*getHora() - 60*getMinuto()); 
 } 
 
 public final void setHora(int h) 
 { 
 int hh = ((h >= 0 && h < 24)? h : 0); 
 tempo = hh*3600 + getMinuto()*60 + getSegundo(); 
 } 
 public final void setMinuto(int m) 
 { 
 int mm = ((m >= 0 && m < 60)? m : 0); 
 tempo = getHora()*3600 + mm*60 + getSegundo(); 
 } 
 public final void setSegundo(int s) 
 { 
 int ss = ((s >= 0 && s < 60)? s : 0); 
 tempo = getHora()*3600 + getMinuto()*60 + ss; 
 } 
 
A implementação dos getters e 
setters muda, pois estes métodos 
dependem de como são 
representados os campos da 
classe. 
public class UsaHorario { 
 public static void main(String args[]) 
 { 
 Horario h = new Horario(); 
 System.out.println(h.toString()); 
 h.setHora(15); 
 h.setMinuto(30); 
 System.out.println(h); 
 h = new Horario(20,60,99); 
 System.out.println(h); 
 } 
} 
© ELFS 59 
3. Projeto de Classes: Campos e Métodos 
 @Override 
 public String toString() 
 { 
 DecimalFormat df = new DecimalFormat("00"); 
 return (df.format(getHora()) + ":" + 
 df.format(getMinuto()) + ":" + df.format(getSegundo())); 
 } 
UsaHorario.java 
Como a API da classe não mudou, 
a mesma classe usuária anterior 
pode ser usada agora. 
O método toString() também 
continua inalterado, pois utiliza 
os getters. 
© ELFS 60 
•  Uma classe pode conter vários métodos com o mesmo nome, desde que as 
assinaturas dos métodos sejam diferentes. Isto é chamado de sobrecarga de 
método. 
•  Assinatura: combinação do nome do método com sua lista de parâmetros. 
 
 
•  Quando um método sobrecarregado é chamado, o compilador seleciona o 
método adequado examinando sua assinatura. 
•  Em geral, os construtores de uma classe são métodos sobrecarregados. 
3. Projeto de Classes: Campos e Métodos 
public int quadrado(int x) 
{ 
 return x * x; 
} 
 
public double quadrado(double x) 
{ 
 return x * x; 
} 
Assinatura: quadrado.int 
Assinatura: quadrado.double 
Se houvesse um outro método: 
public double quadrado(int z) 
o que ocorreria? 
© ELFS 61 
3. Projeto de Classes: Campos e Métodos 
Exercício 1. Criar uma classe Retangulo com campos privados comprimento e 
largura. A classe deve ter métodos para calcular o perímetro e a área do 
retângulo. A classe deve conter os getters e setters necessários. Os setters devem 
verificar se os valores dos campos são válidos. Valores válidos são números de 
ponto flutuante no intervalo [1, 20]. O valor default deve ser 1. 
 
 
Exercício 2. Implementar a classe Data. A classe deve conter os getters e setters 
necessários. Os demais métodos da classe são tais que: 
•  avancar(): deve avançar a data em 1 dia. 
•  voltar(): deve retroceder a data em um 1 dia. 
•  anoBissexto(): deve retornar true se 
 ((ano % 100 <> 0) && (ano % 4 == 0)) || ((ano % 100 == 0) && (ano % 400 == 0)) 
•  diasDoMes(): deve retornar o número de dias do mês, levando em conta se o 
ano é bissexto ou não. 
•  paraFrente(int n): deve chamar avancar() n vezes. 
•  paraTras(int n): deve chamar o método voltar() n vezes.

Continue navegando