Upload
manuel-menezes-de-sequeira
View
414
Download
1
Embed Size (px)
DESCRIPTION
Fundamentos da Programação 13: • Polimorfismo de subtipos • Análise, desenho e implementação Apresentação 13 da unidade curricular de Fundamentos de Programação da Universidade Europeia. Alterações de Manuel Menezes de Sequeira sobre versão original por vários autores do DCTI do ISCTE-IUL, incluindo Luís Nunes, Ricardo Ribeiro, André Santos e o próprio Manuel Menezes de Sequeira.
Citation preview
Apresentação 13
Polimorfismo de subtiposAnálise, desenho e implementação
Na apresentação anterior … Paradigmas da programação
Programação orientada por objectos
Modularização em pacotes
2013/2014 Fundamentos de Programação 2
Employee
public class Employee {
private String name; private String ssn;
public Employee(final String name, final String ssn) { this.name = name; this.ssn = ssn; }
public String getName() { return name; }
public String getSsn() { return ssn; }
@Override public String toString() { return "(" + getName() + ", " + getSsn() + ")"; }
}
2013/2014 Fundamentos de Programação 3
Que é isto? Veremos à frente…
Generalização (relação)
2013/2014 Fundamentos de Programação 4
Employee
Supervisor
Relação de generalização
Esp
ecia
lizaçã
o
Genera
lizaç
ão
• Um Supervisor é um Employee.• Um Employee pode ser um Supervisor.
Herança
public class Supervisor extends Employee {
private int level;
public Supervisor(final String name, final String ssn, final int level) { … }
public int getLevel() { return level; }
@Override public String toString() { return "(" + getName() + ", " + getSsn() + ", " + getLevel() + ")"; }}
2013/2014 Fundamentos de Programação 5
Um Supervisor é um Employee.
Sobrepõe-se ao método com a mesma assinatura na classe base Employee.
Novo método específico da classe Supervisor.
Generalização (relação)
2013/2014 Fundamentos de Programação 6
Employee
Supervisor
Esp
ecia
lizaçã
o
Genera
lizaç
ão
Classe base ou superclasse.
Classe derivada ou subclasse.
Herança
Classe derivada deriva da classe base(subclasse deriva da superclasse)
Membros são herdados e mantêm categoria de acesso
Relação é um – Referências do tipo da classe base podem referir-se a objectos de classes derivadas
Exemplo
Supervisor supervisor = new Supervisor("Guilhermina", "123456789", 3);
Employee employee = new Supervisor("Felisberto", "987654321", 5);
2013/2014 Fundamentos de Programação 7
Sobreposição
Método de classe derivada pode sobrepor-se a método de classe base
Sobreposição é especialização
Regras Mesma assinatura e tipo de devolução
compatível Método na classe base não privado e não final Método na classe derivada com acessibilidade
igual ou superior2013/2014 Fundamentos de Programação 8
Na realidade tem de ser co-variante, ou seja, o tipo de devolução do método na classe derivada deriva de (ou é igual a) o tipo de devolução na classe base.
Um método final não pode ser especializado.
Categorias de acesso (de novo) Características ou membros podem ser
private – acesso apenas por outros membros da mesma classe
package-private (sem qualificador) – adicionalmente, acesso por membros de classes do mesmo pacote
protected – adicionalmente, acesso por membros de classes derivadas
public – acesso universal2013/2014 Fundamentos de Programação 9
Ace
ssib
ilidad
e c
resc
ente
O Java promove a promisquidade entre objectos…
Interfaces de uma classe
Própria classe Membros da classe e membros não privados de classes
base
Classe do mesmo pacote Membros não privados da classe ou suas bases
Classe derivada Membros protegidos ou públicos da classe ou suas
bases
Outra classe Membros públicos da classe ou suas bases
2013/2014 Fundamentos de Programação 10
Exemplo
ArrayList<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("João Maria", "123456789"));employees.add(new Supervisor("Ana Maria", "987654321", 4));…
for (Employee employee : employees) out.println(employee.toString());
2013/2014 Fundamentos de Programação 11
Qual o método toString() executado?
Invocação da operação toString().
Organização
2013/2014 Fundamentos de Programação 12
employees : «ref» ArrayList<Employee>
: ArrayList<Employee>
: «ref» Employee
0
: «ref» Employee
1
: Employeename = “João Maria”ssn = “123456789”
: Supervisorname = “Ana Maria”ssn = “987654321”level = 4
Possível porque a classe Supervisor deriva da classe Employee, ou seja, possível porque um Supervisor é (sempre também) um Employee.
Resultado
2013/2014 Fundamentos de Programação 13
O resultado depende do tipo do objecto e não do tipo da referência! Isso acontece porque o método toString é polimórfico ou virtual.
_(João Maria, 123456789)_(João Maria, 123456789)(Ana Maria, 987654321, 4)_
Polimorfismo (de subtipos) Capacidade de um objecto tomar várias
formas A forma descrita pela classe a que pertence As formas descritas pelas classes acima na
hierarquia a que pertence
Objecto pode ser referenciado por referências do tipo da classe a que pertence ou de classes acima na hierarquia (mais genéricas)
2013/2014 Fundamentos de Programação 14
Princípio da substituição de Liskov
Seja p(x) uma propriedade demonstrável acerca de objectos x do tipo B. Então, p(y) também deve verificar-se para objectos y do tipo D onde D é um subtipo de B.
Barbara H. Liskov e Jeannette M. Wing, «A Behavioral Notion of Subtyping», ACM Transactions m Programming Languages and Systems, Volume 16, N.º 6, Novembro de 1994, pp. 1811-1841.
Ver http://en.wikipedia.org/wiki/Liskov_substitution_principle.
2013/2014 Fundamentos de Programação 15
Tem de ser o programador a garantir que este princípio se verifica!
O que aparece na consola?Supervisor supervisor = new Supervisor("Guilhermina", "123456789", 3);Employee anEmployee = new Supervisor("Felisberto", "987654321", 5);Employee anotherEmployee = new Employee("Elvira", "111111111");
out.println(supervisor.toString());out.println(anEmployee.toString());out.println(anotherEmployee.toString());
2013/2014 Fundamentos de Programação 16
_(Guilhermina, 123456789, 3)_(Guilhermina, 123456789, 3)(Felisberto, 987654321, 5)_
(Guilhermina, 123456789, 3)(Felisberto, 987654321, 5)(Elvira, 111111111)_
Polimorfismo: operações e métodos
Uma operação polimórfica ou virtual pode ter várias implementações
A uma implementação de uma operação chama-se método
A uma operação polimórfica podem corresponder diferentes métodos, cada um em sua classe
Todas as operações em Java são polimórficas, com excepção das qualificadas com private
Uma classe é polimórfica se tiver pelo menos uma operação polimórfica
2013/2014 Fundamentos de Programação 17
Polimorfismo: operações e métodos
Invoca-se uma operação sobre um objecto de uma classe para atingir um objectivo
Invocação de uma operação leva à execução do método apropriado, ou seja, leva à execução da implementação apropriada da operação
Polimorfismo Invocação de uma operação pode levar à execução de
diferentes métodos Método efectivamente executado depende da classe do
objecto sobre o qual a operação é invocada Método executado não depende do tipo da referência para
o objecto utilizado2013/2014 Fundamentos de Programação 18
Simplificação… invocações internas podem levar à execução de métodos privados directamente.
A classe Object
public class Employee extends Object {
private String name; private String ssn;
public Employee(final String name, final String ssn) { this.name = name; this.ssn = ssn; }
public String getName() { return name; }
public String getSsn() { return ssn; }
@Override public String toString() { return "(" + getName() + ", " + getSsn() + ")"; }
}
2013/2014 Fundamentos de Programação 19
Agora percebe-se! A classe Object declara a operação toString() e define imediatamente um correspondente método. Esta é uma sua especialização.
Se uma classe não derivar explicitamente de outra, derivará implicitamente da classe Object, que está no topo da hierarquia de classes do Java.
Ligação estática vs. dinâmica Ligação (binding)
Associação entre a invocação de uma operação e a execução de um método
Ligação estática Operações não polimórficas, invocações através de super
Associação estabelecida em tempo de compilação
Ligação dinâmica Operações polimórficas Associação estabelecida apenas em tempo de
execução2013/2014 Fundamentos de Programação 20
Que é isto? Veremos à frente…
Métodos finais
Classe derivada não é obrigada a fornecer método para operação da classe base
Classe base pode proibir às classes derivadas a sobreposição de um seu método, que se dirá ser um método final
Razão para um método ser final: Programador que forneceu o método na classe base
entendeu que classes derivadas não deveriam poder especializar o modo de funcionamento desse método
2013/2014 Fundamentos de Programação 21
Uma ajudinha da classe basepublic class Base {
public String className() { return "Base"; }
}
public class Derived extends Base {
@Override public String className() { return "Derived"; }
public void testCalls() { final Base base = (Base)this;
out.println("Through this: " + this.className()); out.println("Through base: " + base.className()); out.println("Through super: " + super.className()); }}
2013/2014 Fundamentos de Programação 22
_Through this: Derived_Through this: DerivedThrough base: Derived_
Through this: DerivedThrough base: DerivedThrough super: Base_
Análise: conceitos
Veículo
Motociclo
Automóvel
Honda NX 650
Audi TT
2013/2014 Fundamentos de Programação 23
Vehicle
Car
Motorcycle
AudiTt
HondaNx650
Análise inicial pode resultar num dicionário ou glossário do domínio.
Análise: relações
Um Automóvel é um Veículo Um Motociclo é um Veículo Uma Honda NX 650 é um Motociclo Um Audi TT é um Automóvel
2013/2014 Fundamentos de Programação 24
Vehicle
Car Motorcycle
AudiTt HondaNx650
Pode refinar-se o dicionário ou glossário do domínio, acrescentando as relações entre conceitos.
Desenho
2013/2014 Fundamentos de Programação 25
Vehicle
Car Motorcycle
AudiTt HondaNx650
……
PropriedadesOperações
……
……
……
……
Implementação
public class Vehicle { …}
public class Car extends Vehicle { …}
public class Motorcycle extends Vehicle { …}
public class HondaNx650 extends Motorcycle { …}
public class AudiTt extends Car { …}
2013/2014 Fundamentos de Programação 26
Conceitos abstractos e concretos Conceito abstracto – Sem instâncias no domínio
em causa
Conceito concreto – Com instâncias no domínio em causa
Conceitos identificados são abstractos ou concretos?
Dependendo do domínio e seu modelo… Veículo abstracto; Automóvel concreto; Audi TT caso
particular de Automóvel Veículo e Automóvel abstractos; Audi TT concreto
2013/2014 Fundamentos de Programação 27
Análise e desenho
HIPÓTESE 1 HIPÓTESE 2
2013/2014 Fundamentos de Programação 28
Vehicle
Car Motorcycle
Vehicle
Car Motorcycle
AudiTt HondaNx650
As classes abstractas, correspondentes aos conceitos abstractos, têm o nome em itálico.
É boa prática que as classes concretas sejam folhas na hierarquia.
Implementação: hipótese 1public abstract class Vehicle { …}
public class Car extends Vehicle { …}
public class Motorcycle extends Vehicle { …}
2013/2014 Fundamentos de Programação 29
Implementação: hipótese 2public abstract class Vehicle { …}
public abstract class Car extends Vehicle { …}
public abstract class Motorcycle extends Vehicle { …}
public class HondaNx650 extends Motorcycle { …}
public class AudiTt extends Car { …}
2013/2014 Fundamentos de Programação 30
Caixa de ferramentas: Position
public class Position {
private final double x; private final double y;
public Position(final double x, final double y) { this.x = x; this.y = y; }
public final double getX() { return x; }
public final double getY() { return y; } …}
2013/2014 Fundamentos de Programação 31
Tipo de referência, pois é uma classe. Mas classe de valor, pois o que conta é a igualdade, e não a identidade.
Caixa de ferramentas: Sizepublic class Size {
private final double width; private final double height;
public Size(final double width, final double height) { this.width = width; this.height = height; }
public final double getWidth() { return width; }
public final double getHeight () { return height; } …}2013/2014 Fundamentos de Programação 32
Apesar de ter também dois atributos do tipo double, um Size não é uma Position.
Tipo de referência, pois é uma classe. Mas classe de valor, pois o que conta é a igualdade, e não a identidade.
Caixa de ferramentas: Boxpublic class Box {
private final Position topLeftCornerPosition; private final Size size;
public Box(final Position topLeftCornerPosition, final Size size) { this.topLeftCornerPosition = topLeftCornerPosition; this.size = size; }
public final Position getTopLeftCornerPosition() { return topLeftCornerPosition; }
public final Size getSize() { return size; }
…
}
2013/2014 Fundamentos de Programação 33
Uma Box não é nem uma Position, nem um Size, mas é representada por uma Position e por um Size.
Tipo de referência, pois é uma classe. Mas classe de valor, pois o que conta é a igualdade, e não a identidade.
Análise: conceitos
Figura
Forma (abstrato)
Círculo
Quadrado
2013/2014 Fundamentos de Programação 34
Figure
Circle
Shape
Square
Análise: relações
Uma Figura é composta de Formas Um Círculo é uma Forma Um Quadrado é uma Forma
2013/2014 Fundamentos de Programação 35
Shape
Circle Square
Figure
Relação de composição.
Desenho
2013/2014 Fundamentos de Programação 36
Shape
Circle Square
……
……
……
Figure
……
Implementação
public class Figure { private ArrayList<Shape> shapes; …}
public abstract class Shape { …}
public class Circle extends Shape { …}
public class Square extends Shape { …}2013/2014 Fundamentos de Programação 37
Tipos de referência, pois são classes. Classes de referência, pois o que conta é a identidade, e não a igualdade.
Implementação: Shape
public abstract class Shape {
private Position position;
public Shape(final Position position) { this.position = position; }
public final Position getPosition() { return position; }
public abstract double getArea(); public abstract double getPerimeter(); public abstract Box getBoundingBox();
public void moveTo(final Position newPosition) { position = newPosition; }
}2013/2014 Fundamentos de Programação 38
Operações abstractas, ou seja, operações sem qualquer implementação disponível até este nível da hierarquia.
Qual a área de uma “forma”??
Tipo de referência, pois é uma classe. Classe de referência, pois o que conta é a identidade, e não a igualdade.
Implementação: Circle
public class Circle extends Shape {
private double radius;
public Circle(final Position position, final double radius) { super(position); this.radius = radius; }
public final double getRadius() { return radius; }
…
2013/2014 Fundamentos de Programação 39
Um Circle é uma Shape e a classe Circle herda a implementação da classe Shape. É necessário apenas
um atributo adicional, correspondente a uma das duas propriedades de um círculo (o raio), já que a posição do centro é herdada da classe Shape.
Uma ajudinha da classe base…
Tipo de referência, pois é uma classe. Classe de referência, pois o que conta é a identidade, e não a igualdade.
Implementação: Circle
…
@Override public double getArea() { return Math.PI * getRadius() * getRadius(); }
@Override public double getPerimeter() { return 2.0 * Math.PI * getRadius(); }
@Override public Box getBoundingBox() { return new Box( new Position(getPosition().getX() - getRadius(), getPosition().getY() - getRadius()), new Size(2.0 * getRadius(), 2.0 * getRadius()) ); }}
2013/2014 Fundamentos de Programação 40
Fornece-se implementações, ou seja, métodos, para cada uma das operações abstractas da classe Shape.
Qual a área de um círculo? Fácil, π × r2.
Desenho pormenorizado
2013/2014 Fundamentos de Programação 41
Shape
Circle Square
- position : Position + Shape(position : Position)+ getPosition() : Position+ getArea() : double+ getPerimeter() : double+ getBoundingBox() : Box+ moveTo(newPosition : Position)
- radius : double+ Circle(position : Position, radius : double)+ getRadius() : double+ getArea() : double+ getPerimeter() : double+ getBoundingBox() : Box
Figure
Símbolo
Categoria de acesso
- private
~ package-private
# protected
+ public
Desenho pormenorizado
2013/2014 Fundamentos de Programação 42
Shape
Circle Square
- position : Position «constructors»
+ Shape(position : Position)
- radius : double«constructors»
+ Circle(position : Position, radius : double)
Figure
«inspectors»+ getPosition() : Position+ getArea() : double+ getPerimeter() : double+ getBoundingBox() : Box
«modifiers»+ moveTo(newPosition : Position)«inspectors»
+ getRadius() : double+ getArea() : double+ getPerimeter() : double+ getBoundingBox() : Box
Classes abstractas
Uma operação com qualificador abstract é uma simples declaração da operação
Uma operação sem qualificador abstract inclui também a definição de um método correspondente, que a implementa
Uma classe com uma operação abstracta tem de ser uma classe abstracta
Uma classe é abstracta se tiver o qualificador abstract
2013/2014 Fundamentos de Programação 43
Classes abstractas
Uma classe não abstracta diz-se uma classe concreta
Uma classe abstracta não pode ser instanciada, i.e., não se podem construir objectos de uma classe abstracta
Uma classe derivada directamente de uma classe abstracta só poderá ser concreta se implementar cada uma das operações abstractas da classe abstracta
2013/2014 Fundamentos de Programação 44
A reter...
Generalização – Relação entre duas classes, base e derivada, em que a derivada especializa a base, que por sua vez generaliza a derivada
Polimorfismo – Um mesmo objecto pode ser visto de formas diferentes consoante o tipo da referência usada para o referenciar: uma mesma referência pode referenciar objectos de diferentes classes
Operação abstracta – Uma operações declarada numa dada classe mas não implementada nessa classe
Classe abstracta – Uma classe que não pode ser instanciada, i.e., da qual não existem objectos; usualmente as classes abstractas têm pelo menos uma operação abstracta
2013/2014 Fundamentos de Programação 45
Sumário
Polimorfismo de subtipos Classes e operações polimórficas Herança Ligação estática e ligação dinâmica Classes abstractas e classes concretas Operações abstractas
Análise, desenho e implementação Dicionário do domínio Conceitos Conceitos concretos e conceitos abstractos
2013/2014 Fundamentos de Programação 46