Conta

Propaganda
Programação por Objectos
Java
Parte 5: Associações
LEEC@IST
Java – 1/32
Associação – revisão
• Uma associação representa uma referência
entre objectos.
• Numa associação são definidos:
– Identificador – termo descritivo da associação.
– Papeis (role) representados pela associação em
cada uma das classes relacionadas.
– Multiplicidade – número de objectos associados
em cada instância da associação.
LEEC@IST
Java – 2/32
Associação (1)
• Associação: representada por atributos de tipo
classe do associado.
1. A associação é definitivamente estabelecida
quando ambos os atributos forem inicializados.
2. A eliminação da associação exige que os dois
atributos deixem de referenciar o outro objecto
associado.
LEEC@IST
Java – 3/32
Associação (2)
Pessoa
1
dono
public class Pessoa {
Conta conta;
...
Pessoa(){
conta = null;
...
}
void associarConta(Conta conta) {
this.conta = conta;
}
}
LEEC@IST
0..1
Conta
conta
public class Conta{
Pessoa dono;
...
Conta(Pessoa dono){
this.dono = dono;
...
}
}
Java – 4/32
Associação (3)
• Associações dirigidas: no Java, apenas a classe
partida da seta contém o atributo para a classe de
chegada.
• Multiplicidade das associações: no Java, a
multiplicidade distinta de 0..1 e 1 é implementada por
atributos de tipo tabelas, Vector, … nas classes
associadas.
• Associações que transportam informação: no Java,
as classes associadas possuem um atributo extra para
a classe de associação.
LEEC@IST
Java – 5/32
Associação (4)
Pessoa
reside
public class Pessoa {
Conta conta;
Endereço reside;
...
void Pessoa(Endereço endereço) {
conta = null;
reside = endereço;
...
}
}
LEEC@IST
Endereço
public class Endereço {
String rua;
...
}
Java – 6/32
Associação (5)
Pessoa
1
dono
0..10
Conta
contas
public class Pessoa {
public class Conta{
int numProxConta=0;
Pessoa dono;
static final int numMaxConta=10;
...
Conta[] conta;
Conta(Pessoa dono){
...
this.dono = dono;
Pessoa() {
conta = new Conta[numMaxConta];
}
}
}
void associarConta(Conta conta){
if (numProxConta<numMaxConta)
this.conta[numProxConta++] = conta;
else
System.out.println(“Número máximo atingido!");
}
}
LEEC@IST
Java – 7/32
Associação (6)
Pessoa
1..100
1
empregado
Empresa
empregador
Emprego
~ vencimento: float
~ dataEntrada: long
public class Pessoa {
Empresa empregador;
Emprego emprego;
...
}
LEEC@IST
public class Emprego {
float vencimento;
long dataEntrada;
...
}
Java – 8/32
Associação (7)
public class Empresa {
int numProxContrato=0;
static final int numMaxContrato=100;
Object[][] ee; // par(empregado,emprego)
...
Empresa() {
ee = new Object[numMaxContrato][2];
...
}
void novoContrato(Pessoa empregado, Emprego emprego) {
if (numProxContrato<numMaxContrato) {
ee[numProxContrato][0]=(Object)empregado;
ee[numProxContrato++][1]=(Object)emprego;
} else System.out.println(“Número máx atingido!”);
}
}
LEEC@IST
Java – 9/32
Associação (8)
•
É da responsabilidade do programador garantir o
correcto estabelecimento das associações e
manutenção da sua coerência.
LEEC@IST
Java – 10/32
Classes aninhadas (1)
• Uma classe aninhada é uma classe definida dentro de
outra classe.
• Uma classe aninhada é um membro da classe que a
envolve:
– A classe aninhada e a classe que a envolve partilham uma
relação de confiança em que cada uma pode aceder a todos os
membros da outra (privados ou não).
– As classes aninhadas podem ter qualificadores de visibilidade
próprios dos membros de classe (private, protected, public, ou
por omissão, de pacote).
LEEC@IST
Java – 11/32
Classes aninhadas (2)
• Uma classe aninhada pode estender qualquer outra
classe, incluindo a classe que a envolve.
• Qualquer classe, com excepção da classe que a
envolve, pode estender a classe aninhada, desde
que tenha acesso à mesma, contudo a subclasse
não herda os privilégios de acesso que a classe
aninhada tem com a classe que a envolve.
• Tal como qualquer classe não aninhada, uma classe
aninhada pode ser declarada final ou abstract.
LEEC@IST
Java – 12/32
Classes aninhadas (3)
• Uma classe aninhada pode ou não ser estática:
– Uma classe aninhada estática permite estruturar
tipos em contextos onde os tipos façam sentido.
– Uma classe aninhada não estática define uma
relação especial entre o objecto aninhado e o
objecto que o envolve.
LEEC@IST
Java – 13/32
Classes aninhadas
estáticas (1)
• Quando uma classe aninhada é estática, comportase como uma classe não aninhada, excepto que:
– O seu nome é definido pela classe envolvente (expresso na
forma ClasseEnvolvente.ClasseAninhada).
– A sua acessibilidade é definida pela classe envolvente: a
classe aninhada é acessível apenas se a classe envolvente
é acessível.
– Uma classe aninhada pode aceder a todos os membros da
classe que a envolve (privados ou não), incluindo membros
herdados (a membros não estáticos apenas através de uma
referência apropriada).
LEEC@IST
Java – 14/32
Classes aninhadas
estáticas (2)
public class Conta {
private long quantia;
private Pessoa dono;
public static class Permissão {
public boolean levantar, fechar;
}
public Permissão permissãoPara(Pessoa p) {
Permissão perm = new Permissão();
perm.levantar = podeLevantar(p);
perm.fechar = podeFechar(p);
return perm;
}
// ... definir podeLevantar e podeFechar
}
LEEC@IST
Java – 15/32
Classes aninhadas
estáticas (3)
•
Relativamente ao exemplo anterior:
– Num objecto mc do tipo Conta, a permissão para o dono
da conta pode ser obtida da seguinte forma:
•
Conta.Permissão perm = mc.permissãoPara(dono);
– O javac gera os seguintes ficheiros:
•
•
LEEC@IST
Conta.class
Conta$Permissão.class
Java – 16/32
Classes aninhadas
não estáticas (1)
• Quando uma classe aninhada não é estática,
comporta-se como uma classe não aninhada,
excepto que:
– Não pode conter membros estáticos (incluindo
classes aninhadas estáticas), com a excepção de
atributos simultaneamente final e static.
• Uma instância de uma classe aninhada não estática
está associada a uma instância da classe que a
envolve.
LEEC@IST
Java – 17/32
Classes aninhadas
não estáticas (2)
public class Conta {
private long número;
private long quantia;
private Pessoa dono;
private Acção últimaAcção;
public class Acção {
private String acção;
private long quantia;
Acção(String acção, long quantia) {
this.acção = acção;
this.quantia = quantia;
}
public String toString() {
//identifica a conta que a envolve
return número+": "+acção+" "+quantia;
}
}
LEEC@IST
Java – 18/32
Classes aninhadas
não estáticas (3)
// ... Continuação do slide anterior
public void depositar(long quantia) {
this.quantia += quantia;
últimaAcção = new Acção("depositar", quantia);
}
public void levantar(long quantia) {
this.quantia -= quantia;
últimaAcção = new Acção(“levantar", quantia);
}
// ...
}
LEEC@IST
Java – 19/32
Classes aninhadas
não estáticas (4)
•
Relativamente ao exemplo anterior:
– A instrução que cria a última acção no depósito e
levantamento é equivalente a:
•
•
últimaAcção = this.new Acção("depositar", quantia);
últimaAcção = this.new Acção("levantar", quantia);
– O método toString acede directamente ao atributo
número da classe Conta que o envolve.
•
•
LEEC@IST
Uma classe aninhada pode aceder directamente a todos
os membros da classe que a envolve, incluindo
atributos e métodos privados.
A classe envolvente também pode aceder aos membros
privados da classe aninhada, mas apenas através de
uma referência explícita para o objecto da classe
aninhada (últimaAcção).
Java – 20/32
Classes aninhadas
não estáticas (5)
•
Relativamente ao exemplo anterior (cont):
– Um objecto da classe aninhada está sempre associado
a um objecto da classe que o envolve, contudo o
recíproco não é verdadeiro.
• Uma classe envolvente pode não ter associado um objecto da
classe aninhada, ou pode ter vários.
• Quando o método depositar cria um objecto Acção, uma
referência para o objecto Conta com quem está associado
é automaticamente guardada no novo objecto Acção.
– O nome da referência para o objecto envolvente é o this
precedido pelo nome da classe envolvente, uma forma de thisqualificado.
– Alternativamente, o método toString podia aceder ao número
do objecto Conta com quem está associado da seguinte forma:
» return Conta.this.número+": "+acção+" "+quantia;
LEEC@IST
Java – 21/32
Classes aninhadas
não estáticas (6)
•
Relativamente ao exemplo anterior (continuação):
– O javac gera os seguintes ficheiros:
• Conta.class
• Conta$Acção.class
LEEC@IST
Java – 22/32
Classes aninhadas
não estáticas (7)
• Um método de transferência de uma certa quantia de
uma outra conta para a conta actual…
public void transferir(Conta outra, long quantia) {
outra.levantar(quantia);
depositar(quantia);
últimaAcção=this.new Acção("transferir-d",quantia);
outra.últimaAcção=outra.new Acção("transferir-l",quantia);
}
LEEC@IST
Java – 23/32
Classes aninhadas
não estáticas (8)
•
Os atributos e métodos de uma classe aninhada podem
esconder alguns atributos e métodos da classe que a envolve
de duas formas distintas:
– Um atributo ou método, declarado na classe envolvente, é
redeclarado na classe aninhada.
– Um atributo ou método, declarado na classe envolvente, é herdado
pela classe aninhada.
•
•
Em ambos os casos, o uso do nome simples na classe
aninhada é sempre relativo à classe aninhada.
Para se aceder ao atributo ou método da classe envolvente
deve usar-se explicitamente o this-qualificado.
LEEC@IST
Java – 24/32
Associação (9)
• As associações podem ainda ser implementadas
com recurso às classes aninhadas
(ver slide 31 de agregação/composição (4)).
LEEC@IST
Java – 25/32
Agregação/Composição –
revisão (1)
• A agregação/composição é uma associação, que
denota uma relação do todo ser formado por partes.
• A agregação/composição é dita como sendo uma
relação de “has-a”.
LEEC@IST
Java – 26/32
Agregação/Composição –
revisão (2)
• A agregação é uma associação, que denota uma
relação do todo ser formado por partes.
todo
parte
• Na composição, o desaparecimento do todo
conduz ao desaparecimento das partes.
todo
LEEC@IST
parte
Java – 27/32
Agregação/Composição (1)
• A agregação/composição pode ser implementada
em Java tal como uma associação:
– Atributos de tipo referência.
– Classes aninhadas.
• Relativamente à composição, é necessário ainda
garantir a coerência sobre o desaparecimento do
todo implicar a desaparecimento das partes.
LEEC@IST
Java – 28/32
Agregação/Composição (2)
1
Empresa
1..10
Departamento
public class Empresa {
int numProxDepartamento = 0;
static final int numMaxDepartamentos = 10;
Departamento departamentos[];
...
Empresa() {
departamentos = new Departamento[numMaxDepartamentos];
...
}
LEEC@IST
Java – 29/32
Agregação/Composição (3)
// ... Continuação do slide anterior
void novoDepartamento() {
if (numProxDepartamento<numMaxDepartamentos)
departamentos[numProxDepartamento++]
= new Departamento(this);
else System.out.println(“Número máx atingido!”);
}
}
public class Departamento {
Empresa empresa;
...
Departamento(Empresa e) {
empresa = e;
}
}
LEEC@IST
Java – 30/32
Agregação/Composição (4)
• Alternativamente, usando classes aninhadas:
– A classe Departamento é definida como classe aninhada
da classe Empresa.
– Deixa de ser necessário guardar uma referência da classe
Departamento para a classe Empresa, pois esta é
disponibilizada implicitamente pelo Java através do thisqualificado.
LEEC@IST
Java – 31/32
Agregação/Composição (5)
public class Empresa {
int numProxDepartamento = 0;
static final int numMaxDepartamentos = 10;
Departamento departamentos[];
...
public class Departamento {...}
Empresa() {
departamentos = new Departamento[numMaxDepartamentos];
...
}
void novoDepartamento() {
if (numProxDepartamento<numMaxDepartamentos)
departamentos[numProxDepartamento++]
= new Departamento();
else System.out.println(“Número máx atingido!”);
}
LEEC@IST
Java – 32/32
Download