Métodos de Programação II
(Mestrado Integrado em Engenharia de Comunicações)
1º Ano, 2º Semestre
Tipos Genéricos, a classe ArrayList,
Hierarquias de classes e Herança em Java
Métodos Programação II
1
Tipos genéricos em Java1.5
• Uma classe pode ser definida à custa de um tipo genérico.
Este é definido usando parâmetros de “tipo”
(i.e. não primitivos).
• Usando este conceito, podemos ter uma infinidade de
variantes de uma classe. Exemplo:
public class Ponto<T>
{ // tipo genérico Ponto<T>
private T x;
private T y;
// Métodos
public Ponto(T cx, T cy) { this.x = cx; this.y = cy; }
public T getX() { return this.x; }
public T getY() { return this.y; }
public void setX(T cx) { this.x = cx }
...
}
• Podemos declarar: Ponto<Integer> c = new Ponto<Integer>();
• Ou então: Ponto<Double> d = new Ponto<Double>();
• Usando assim tipos parametrizados…
Métodos Programação II
2
Primeiras Colecções – a classe
ArrayList<E>
Tipo
referenciado
• O Java1.5. oferece um conjunto de classes (que
implementam estruturas de dados tradicionais) para
armazenamento de objectos.
• Estas, agrupam os objectos em unidades compactas e
estruturadas, implementando também as necessárias
operações para a correcta manipulação e organização
dos dados.
• Um exemplo é a classe ArrayList que implementa a
estrutura de dados vector de dados (array dinâmico) mas
sem restrições de crescimento.
• Um ArrayList é uma sequência de elementos (tem uma
ordem definida pela adição de novos elementos)
Métodos Programação II
3
Construção & métodos de
ArrayList<E>
• Construção:
– ArrayList<Ponto> lista = new ArrayList<Ponto>();
• Operações e seus métodos
– Adição de uma novo elemento ao fim da lista:
lista.add(new Ponto(1,2));
– Adição numa posição definida:
lista.add(3, new Ponto(1,2));
Implica que equals()
esteja implementado
– Eliminar um elemento:
lista.remove(p);
em Ponto
– Eliminar uma posição:
lista.remove(1);
– Obter um obj numa posição: Ponto p2 = lista.get(2);
– Saber a posição de um obj: int index = lista.indexOf(p2);
– Saber tamanho da lista:
int len = lista.size();
– Substituir uma posição:
lista.set(2, new Ponto(3,4));
– Criar um array cópia do ArrayList:
Object a[] = lista.toArray();
Métodos Programação II
4
Exercício:
class Banco usando ArrayList
class Banco
{
private ArrayList<Conta> lista;
private String nome;
private double saldo;
Banco(String n)
{ this.nome = n; this.lista = new ArrayList<Conta>(); this.saldo = 0.0; }
public void taxas(double valor)
{
for(Conta c:this.lista)
c.debito(valor);
}
public double saldo_banco()
{ double temp = 0.0;
for(Conta c:this.lista)
temp += c.getSaldo();
return(temp);
}
}
Métodos Programação II
5
Herança
• Um grande trunfo da programação orientada aos
objectos é a sua capacidade de reutilização de código.
• Reutilização por duas vias:
– Composição de classes: Definir uma nova classe usando
objectos de classes já pré definidas
– Hierarquia de classes: Definir uma nova classe que é uma
especialização da uma classe pré definida: Assim, todo o código
da classe geral é herdade pela nova classe.
– Temos assim, não um plano de classes mas uma hierarquia
Métodos Programação II
6
Herança: Exemplo
• Temos a classe Ponto (2 dimensões) que passamos a chamar
Ponto2D.
• Queremos agora definir uma nova classe para trabalhar no espaço
tridimensional (Ponto3D)
• Esta nova classe de reutilizar todo o código de Ponto2D
adicionando nova informação (neste caso uma terceira dimensão).
Em Java define-se:
Keyword para definir
subclasse
class Ponto3D extends Ponto2D
{ private double z;
Ponto3D(double x, double y, double z)
{ super(x,y); this.z = z;}
Referência à super classe
Public double getZ() // método local a Ponto3D
{ return this.z; }
}
Métodos Programação II
7
Herança em Java
• Definição de uma subclasse implica a definição de um
subtipo!
• Herança simples (uma classe tem um só “progenitor”)
• Herdar e ter “acesso” não é necessariamente a mesma
coisa (pelas questões de visibilidade)
• Três pontos a resolver:
– Redefinição (reescrita) de métodos e variáveis
– Procura de métodos (lookup de métodos dinâmico)
– Criação das instâncias das subclasses.
• Há sempre forma de parar a hierarquia, pela keyword
final. Uma classe definida usando “final class” não pode
ter subclasses. Uma variável ou método final não pode
ser reescrito.
Métodos Programação II
8
Redefinição de métodos
• Um método na subclasse reescreve o método herdado
se tiver a mesma assinatura.
• Exemplo do método toString() em Ponto3D.
class Ponto3D extends Ponto2D
{ ….
public String toString()
{ return super.toString() + “,” + this.z; }
}
• Criação de instâncias:
–
–
–
–
Ponto2D p1 = new Ponto2D(1,2);
Ponto2D p2 = new Ponto3D(1,2,3);
Ponto3D p3 = new Ponto3D(3,2,1);
String t = p2.toString();
Métodos Programação II
Dynamic Binding: compilador
atribui o tipo à variável; o
interpretador pode ter de decidir o
tipo de uma variável.
9
Redefinição de variáveis
public class A
{
int i = 0;
int m() { return this.i; }
}
public class B extends A
{
int this.i = 1; // i de A é “shadowed”
int m() { return this.i; } // m é “overriden”
}
….
A a = new A(); A b = new B();
b.m() // dá como resultado 1 e não 0 !!
Por exemplo, um método de B
poderia ter o seguinte código:
public int mb()
{
this.i = super.i + 10;
return this.i + this.m() + super.m();
}
i -> local
super.i -> i da superclasse
this.m() -> local
super.m() -> m() da superclasse
Métodos Programação II
10
Redefinição: Exemplo
public static void main(String args[])
{
public class C extends A
public class A A a1, a2, a3, a4;
{ a3 = new C(); a4 = new D();
{ private int a; a1 = new A(); a2 = new B();
private a4.metd();
int c;
a1.metd();
public A() { this.a
= 1; } a2.metd(); a3.metd();
C() { this.c = 3; }
out.println("a1.metd()
= " +public
a1.daVal());
public int daVal()
{ return this.a; }
int daVal() { return this.c; }
out.println("a2.metd()
= " +public
a2.daVal());
public void metd()
{ this.a += 10; }
void metd() { this.c += 30 ; }
out.println("a3.metd() = " +public
a3.daVal());
}
out.println("a4.metd()
= "}+ a4.daVal());
public class B extends
A
public class D extends C
}
{
{
private int b;
private int d;
public B() { this.b = 2; }
public D() { this.d = 33; }
public int daVal() { return this.b; }
public int daVal() { return this.d; }
public void metd() { this.b += 20 ; }
public void metd() { this.d = this.d * 10 + 3 ; }
}
}
Métodos Programação II
11
Exemplo
EMPREGADO
GESTOR
MOTORISTA
Métodos Programação II
12
Exemplo
public class Empregado
{ // Variáveis de Classe
public static double salDia = 50.00;
public static double getSalDia() { return salDia; }
// Variáveis de Instância
private String nome;
private int dias; // dias de trabalho no mês
// Construtores
public Empregado(String nome, int dias)
{ this.dias = dias; this.nome = nome; }
// Métodos de Instância
public int getDias() { return dias; }
public double salario() { return dias * getSalDia(); }
public String getNome() { return nome; }
}
public class Motorista extends Empregado
{ // Variáveis de Classe
public static double valorKm = 0.98;
public class Gestor extends Empregado
public static double mudaValKm(double nvKm)
{ // Variáveis de Instância e Construtores
{ valorKm = nvKm; }
// Variáveis de Instância e Construtores
private double bonus;
private double bonus;
public Gestor(String nm, int dias, double bon)
private int km;
{ super(nm, dias); bonus = bon; }
public Motorista(String nm, int dias, double bon, int km)
// Métodos de Instância
{super(nm, dias); bonus = bon; this.km = km; }
public double getBonus() { return bonus; }
// Métodos de Instância
public double salario()
public double getBonus() { return bonus; }
{ return getSalDia()*this.getDias()*bonus; }
public double salario() {
return getSalDia()*this.getDias()*bonus + (valorKm*km); }
}
Métodos Programação
II
13
}
Interpretação de this em hierarquias de
classes
Invocar a.teste() (sendo a uma instância de SubA) :
A interpretação de this refere-se sempre
ao objecto para onde a mensagem é enviada.
Neste caso, como teste() é um método herdado,
ele é invocado em Super. No entanto como
teste() refere a this.getX(), a procura do método
faz-se na subclass SubA. Aqui acontece
simplesmente o return x, sendo x a variável de
SubA. Assim o resultado desta mensagem é
x = 20.
Em geral, a expressão this.m() onde quer que seja encontrada no código de um
método de instância de uma dada classe da hierarquia, corresponderá sempre
à execução do método m() da classe do receptor da mensagem que despoletou
o algoritmo de procura
Métodos Programação II
14
Hierarquia em Java: classe Object
• A classe Object representa o topo da hierarquia
de classes em Java.
• Uma variável do tipo Object pode fazer
referência para qualquer tipo referenciado.
• Especificam os métodos clone(), equals() e
toString().
• Contém o método getClass() que retorna a classe
a que um objecto pertence.
• Com getClass().getName() obtemos o nome da
classe.
Métodos Programação II
15
Notas finais sobre Herança
• Só podemos user a keyword super uma vez numa expressão e.g. a
expressão super.super.m() é inválida.
• Variáveis e métodos de classe não são herdadas mas as variáveis
podem ser redefinidas. Aos métodos static acontece o inlining
(o compilador substitui invocação por código efectivo) em cada
subclasse.
• Pelo facto de uma variável de um dado tipo estático poder possuir
diferentes tipos dinâmicos (ou formas) em tempo de execução, ela
diz-se polimórfica.
• Polimorfismos das variáveis = princípio da substituição.
• Algoritmo de procura dinâmica de métodos e associação dinâmica!
Permite ao interpretador decidir (em situações de herança) qual o
método a executar.
Métodos Programação II
16
Exercícios
• Definir uma classe Forma.
• Definir a seguinte hierarquia de classes:
• Implementar os métodos apresentados.
• Definir a classe FigGeo que guarda um conjunto de figuras
geométricas.
• Adicionar a classe Quadrado e Elipse (subclasse de Círculo)
• Implementar um método que determina a figura com a maior área e
qual o seu tipo e outro método para o maior perímetro.
• Um método para contabilizar o número de figuras por tipo.
Métodos Programação II
17
Exercícios
• Criar um banco que guarda as contas num ArrayList
• Definir vários novos tipos de conta: conta a prazo, conta
jovem, conta ordenado e conta Capital.
– Prazo, tem uma taxa e um número de dias
– Jovem, tem taxa fixa de 1% ao ano
– Ordenado, dá um plafond de um valor pré definido. Isto é,
permite estar com saldo devedor até ao montante estabelecido.
– Conta Capital, que contém uma taxa de juro variável, indexada
por períodos. A rentabilidade é calculada
sobre estes períodos.
• Calcular os juros que o banco tem de pagar aos seus
clientes.
• Calcular o nº de contas por tipo bem como o saldo total
depositado no banco referente a contas Capital.
Métodos Programação II
18
Download

Métodos de Programação II (Mestrado Integrado em Engenharia de