Definição de classes em Java (introdução)

Propaganda
Definição de classes em Java
(introdução)
PCO / PPO
Departamento de Informática
Faculdade de Ciências da Universidade de Lisboa
Resumo
➡ Introdução à implementação de classes Java
➡
declaração de campos de instância
➡
definição de construtores
➡
definição de métodos de instância
➡
campos e métodos de classe (i.e., “estáticos”)
➡
visibilidade privada, pública e de pacote
➡
documentação de classes no formato Javadoc
➡
anotação de pré-condições
2
Conteúdo de uma classe
- componentes essenciais package some_package;
public class ClassName {
CAMPOS DE INSTÂNCIA
+
CONSTRUTORES
+
MÉTODOS DE INSTÂNCIA
+
CAMPOS/MÉTODOS DE CLASSE (ESTÁTICOS)
}
➡ Campos de instância: definem atributos dos objectos da classe.
➡ Construtores: definem a inicialização dos objectos da classe.
➡ Métodos de instância: métodos que conduzem operações tendo em conta
os valores dos campos de instância.
➡ Campos e métodos de classe (“estáticos”): definem atributos / métodos
globais à classe.
3
package pco.time;
public class TimeOfDay {
...
public TimeOfDay() { ... }
public TimeOfDay(int h, int m) { ... }
public TimeOfDay(TimeOfDay t) { ... }
public int getHours() { ... }
public int getMinutes() { ... }
public void setHours(int h) { ... }
public void setMinutes(int m) { ... }
public String toString() { ... }
public void advanceOneHour() { ... }
public void advanceOneMinute() { ... }
public boolean sameTime(TimeOfDay t) { ... }
public TimeOfDay oneHourLater() { ... }
public TimeOfDay oneMinuteLater() { ... }
public static TimeOfDay midday() { ... }
public static TimeOfDay currentTime() { ... }
...
}
➡ Vamos ver como dar corpo a esta classe para representar a hora do
dia com precisão de minutos. O exemplo completo está disponível no
Moodle.
4
Campos de instância
package pco.time;
public class TimeOfDay {
... int hours;
... int minutes;
...
}
➡ Campos de instância
➡
➡
➡
➡
Definem os atributos de um objecto (instância) da classe.
Estado de um objecto: conjunto de valores associados aos
campos de instância a dado momento durante a execução
Cada campo de instância é definido por um tipo e nome (único) , e
outros modificadores (opcionais).
No exemplo: um objecto TimeOfDay tem sempre associado um
campo hours (para as horas) e um campo minutes (minutos)
5
Visibilidade private
package pco.time;
public class TimeOfDay {
private int hours;
private int minutes;
...
}
➡ O modificador private (privado) limita a visibilidade dos campos ao
código da classe (o inverso de public)
➡
➡
Os campos podem ser acedidos (lidos/escritos) apenas por código
definido na própria classe.
Código em outra classe não poderá aceder aos campos.
➡ Encapsulamento / ocultação de informação (“information hiding”)
➡
➡
desta forma escondem-se detalhes de implementação
o interface entre código cliente e a classe não pode ser feito via
declarações privadas
6
Construtores
package pco.time;
public class TimeOfDay {
private int hours;
private int minutes;
...
public TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
}
➡ Construtores
➡
➡
Definem como um objecto de uma classe é inicializado.
No exemplo: campo hours inicializado com valor de h e campo
minutes com o valor de m.
7
Construtores (2)
package pco.time;
public class TimeOfDay {
...
public TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
public TimeOfDay() {
hours = 0;
minutes = 0;
}
public TimeOfDay(TimeOfDay t) {
hours = t.hours;
minutes = t.minutes;
}
}
➡ Podemos ter vários construtores.
➡ Obs. : O terceiro construtor é expresso c/acessos a campos de t .
8
Uso do operador new
package pco.time;
public class TimeOfDay {
...
public TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
public TimeOfDay() {
hours
= 0;
minutes = 0;
}
public TimeOfDay(TimeOfDay t) {
hours
= t.hours;
minutes = t.minutes;
}
TimeOfDay t =
new TimeOfDay(12, 30);
TimeOfDay t2 =
new TimeOfDay();
TimeOfDay t3 =
new TimeOfDay(t);
...
TimeOfDay
t
•
12
hours
30
minutes
TimeOfDay
t2
•
0
hours
0
minutes
TimeOfDay
t3
•
12
hours
30
minutes
9
Palavra chave this
public TimeOfDay(int hours, int minutes) {
this.hours = hours;
this.minutes = minutes;
}
em alternativa a …
➡
➡
➡
public TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
this refere-se à instância (objecto) em contexto
Analogia possível com Python: this ~ self
Palavra-chave pode ser geralmente omitida no acesso a
atributos, excepto p/desfazer ambiguidades entre nomes de
variáveis em contexto e campos de instância (ex. variante do
construtor acima).
10
Invocação entre construtores
package pco.time;
public class TimeOfDay {
...
public TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
public TimeOfDay() {
this(0,0);
}
public TimeOfDay(TimeOfDay t) {
this(t.hours, t.minutes);
}
}
➡ Alternativa ao código que vimos antes … no exemplo o segundo e
terceiro construtor invocam o primeiro …
➡O
esquema é usado para delegar inicialização a um construtor
“base”, aquele que é o mais “geral”, e assim reutilizar código …
11
Métodos de instância
package pco.time;
public class TimeOfDay {
private int hours;
private int minutes;
...
public int getHours() {
return hours;
}
public int getMinutes() {
return minutes;
}
public void setHours(int h) {
hours = h;
}
public void setMinutes(int m) {
minutes = m;
}
...
➡ Um método de instância define uma operação que pode ser invocada
sobre um objecto da classe.
12
Métodos de instância (2)
package pco.time;
public class TimeOfDay {
...
public String toString() {
StringBuilder sb = new StringBuilder();
if (hours < 10) {
sb.append('0');
}
sb.append(hours);
sb.append(':');
if (minutes < 10) {
sb.append('0');
}
sb.append(minutes);
return sb.toString();
}
}
➡ toString(): devolve representação textual no formato HH:MM.
13
Uso de métodos de instância
(exemplo)
Obs.: Este código pode ser definido em qualquer pacote, já que usa apenas
funcionalidade declarada como public em TimeOfDay .
package any_package;
public class TimeOfDayClient {
public static void main(String[] args) {
TimeOfDay t = new TimeOfDay(9, 30); // > 9:30
int h = t.getHours();
// < 9
int m = t.getMinutes(); // < 30
System.out.println("Hours: "+ h + " Minutes: "+ m);
System.out.println(t.toString()); // “09:30”
t.setHours(h + 1);
// > 10
t.setMinutes(m + 10); // > 40
System.out.println(t.toString()); // “10:40”
}
}
14
Mutabilidade
package pco.time;
public class TimeOfDay {
private int hours;
private int minutes;
...
public void setHours(int h) {
hours = h;
}
public void setMinutes(int m) {
minutes = m;
}
...
➡ setHours
e setMinutes permitem que o estado do objecto seja
alterado após construção.
➡ Objectos TimeOfDay são então mutáveis. A distinção que fazemos é a
seguinte:
➡
➡
objectos imutáveis: estado é inicializado apenas por construtores, não
sendo possível alterá-lo posteriormente
objectos mutáveis: estado pode ser modificado após inicialização
15
Visibilidade de pacote
(“package-protected”)
package pco.time;
class TimeOfDay {
int hours;
int minutes;
...
TimeOfDay(int h, int m) {
hours
= h;
minutes = m;
}
➡ Obs.: Se não usarmos nem public nem private, por omissão as
declarações de campos/métodos visíveis no contexto da classe e
também todas as classes que fazem parte do mesmo pacote.
➡ Se TimeOfDay
tivesse a forma acima, o código cliente do “slide”
anterior teria de estar definido obrigatoriamente no pacote
pco.time
16
Campos e métodos de classe
(“estáticos”)
package pco.time;
public class TimeOfDay {
...
public static final int MINUTES_PER_HOUR = 60;
public static final int HOURS_PER_DAY = 24;
public static TimeOfDay midday() {
return new TimeOfDay(12, 0);
}
...
}
➡
Campos e métodos de classe são declarados com o modificador
static.
➡
As declarações são globais à classe, ao contrário de campos e
métodos de instância.
17
Uso de
campos e métodos de classe
TimeOfDay t =
TimeOfDay.midday();
for (int i=1; i <= TimeOfDay.MINUTES_PER_HOUR; i++) {
t.advanceOneMinute();
}
System.out.println( t.toString() );
➡ Que string é impressa?
➡ Acesso a campos de classe:
➡
➡
TimeOfDay.MINUTES_PER_HOUR
System.out (definido em java.lang.System)
➡ Chamada a método de classe:
➡
TimeOfDay.midday()
18
Campos de classe
e o modificador final
package pco.time;
public class TimeOfDay {
...
public static final int MINUTES_PER_HOUR = 60;
public static final int HOURS_PER_DAY = 24;
public static TimeOfDay midday() {
return new TimeOfDay(12, 0);
}
...
}
➡
O modificador final determina que os valores dos campos de classe são
têm um valor fixo. Chamamos nesse caso aos campos constantes de
classe.
➡
Não podemos redefinir o valor do campo. Por exemplo, a instrução seguinte
causará um erro de compilação:
➡
TimeOfDay.MINUTES_PER_HOUR = 59;
19
Uso de constantes
package pco.time;
public class TimeOfDay {
...
public void advanceOneHour() {
hours ++;
if (hours == HOURS_PER_DAY) {
hours = 0;
}
}
public void advanceOneMinute() {
minutes ++;
if (minutes == MINUTES_PER_HOUR) {
minutes = 0;
advanceOneHour();
}
}
➡
As constantes também podem ser úteis na definição da funcionalidade
da classe.
20
Campos de instância
e o modificador final
package pco.time;
public class TimeOfDay {
private final int hours;
private final int minutes;
...
public void setHours(int h) {
hours = h;
}
public void setMinutes(int m) {
minutes = m;
}
...
X
X
➡
Se usarmos o modificador final para os campos de instância, a tentativa de
atribuição de novos valores aos atributos dará erro de compilação.
➡
Apenas construtores podem atribuir valores a campos de instância assim
declarados.
21
Convenções usuais
de nomeação em Java
➡ Pacotes:
identificadores em letra minúscula separados por
pontos.
➡ Se o código se associar a uma determinada organização é comum
usar o URL invertido do domínio WWW como nome do pacote
➡
ex. pt.ul.fc.di.pco
➡ Nomes de classes começam com maiúsculas.
➡ Nomes de campos e métodos começam com minúsculas, excepto
constantes que usualmente são declaradas usando apenas
maiúsculas.
➡ Convenção “camel-case”: se um nome representar a junção de
duas (ou mais) palavras, cada palavra começa com maísculas.
➡
ex. classes: TimeOfDay
➡
ex. métodos/campos/variáveis: identityMatrix() numColors
StringBuilder
LayoutManager
22
Documentação Javadoc
➡
O utilitário javadoc permite gerar documentação HTML a partir de
código fonte Java. Toda a documentação da Java API é aliás gerada
dessa forma ex. http://docs.oracle.com/javase/8/docs/api/java/lang/
String.html
➡
A documentação é gerada a partir de secções de comentários
começados por /** e terminados por */
23
Documentação Javadoc (classe)
/**
* A class for representing the time of day
* with the precision of minutes.
*
* @author Eduardo Marques, DI/FCUL, 2014
*/
public class TimeOfDay {
…
}
24
Documentação Javadoc (métodos)
/**
* Check for equality against a given {@code TimeOfDay}
* object.
* @param t A {@code TimeOfDay} object
* @return {@code true} if and only if {@code this}
* and {@code t} represent the same time
*/
public boolean sameTime(TimeOfDay t) {
…
}
25
Documentação Javadoc (campos)
/**
* Value for hours.
*/
private int hours;
26
Anotação de pré-condições
/**
* Constructs a new time using supplied
* values for hours and minutes.
* @param h Value for hours
* @param m Value for minutes
*/
//@requires h >= 0 && h < HOURS_PER_DAY
//@requires m >= 0 && m < MINUTES_PER_HOUR
public TimeOfDay(int h, int m) {
hours = h;
minutes = m;
}
➡
Como documentação extra-Javadoc vamos empregar a anotação
@requires , com o propósito de anotar pré-condições que devem
ser garantidas por código cliente.
➡
Ao longo do semestre veremos outros conceitos relacionados com o
paradigma de desenho-por-contrato e também formas de validar e
reportar erros usando excepções.
27
Download