Programação Orientada por Objectos - Aula 2

3,179 views
3,098 views

Published on

Aula teórica 2 da unidade (disciplina) de Programação Orientada por Objectivos para os cursos de LIGE, LEI e LETI no ISCTE-IUL no 2.º semestre do ano lectivo de 2009/2010.

Published in: Education, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
3,179
On SlideShare
0
From Embeds
0
Number of Embeds
817
Actions
Shares
0
Downloads
146
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Programação Orientada por Objectos - Aula 2

  1. 1. Aula 2<br />Polimorfismo de subtipos<br />Análise, desenho e implementação<br />
  2. 2. Na aula anterior …<br />Introdução à programação orientada por objectos<br />Classes, objectos e referências (revisão)<br />Modularização em pacotes<br />Organização em ficheiros e directórios<br />2009/2010<br />Programação Orientada por Objectos<br />2<br />
  3. 3. Employee<br />publicclassEmployee {<br />privateStringname;<br />   privateStringssn;<br />publicEmployee(final Stringname, final Stringssn) {<br />this.name = name;<br />this.ssn = ssn;<br /> }<br />publicStringgetName() {<br />returnname;<br /> }<br />publicStringgetSsn() {<br />returnssn;<br /> }<br /> @Override<br />publicStringtoString() {<br />return "(" + getName() + ", " + getSsn() + ")";<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />3<br />Que é isto? Veremos à frente…<br />
  4. 4. Generalização (relação)<br />2009/2010<br />Programação Orientada por Objectos<br />4<br />Employee<br />Generalização<br />Especialização<br />Supervisor<br />Relação de generalização<br /><ul><li> Um Supervisoré umEmployee.
  5. 5. Um Employeepode ser umSupervisor.</li></li></ul><li>Herança<br />public class Supervisor extends Employee {<br />    private int level;<br />    public Supervisor(final String name, <br /> final String ssn,<br /> final int level) {<br /> …<br /> }<br />    public intgetLevel() {<br /> return level;<br /> }<br /> @Override<br />    public String toString() {<br /> return "(" + getName() + ", " + getSsn() + ", " <br /> + getLevel() + ")";<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />5<br />Um Supervisor é um Employee.<br />Novo método específico da classe Supervisor.<br />Sobrepõe-se ao método com a mesma assinatura na classe base Employee.<br />
  6. 6. Generalização (relação)<br />2009/2010<br />Programação Orientada por Objectos<br />6<br />Classe base ou superclasse.<br />Employee<br />Generalização<br />Especialização<br />Supervisor<br />Classe derivada ou subclasse.<br />
  7. 7. Herança<br />Classe derivada deriva da classe base(subclasse deriva da superclasse)<br />Membros são herdados e mantêm categoria de acesso<br />Relação é um – Referências do tipo da classe base podem referir-se a objectos de classes derivadas<br />Exemplo<br />Supervisor supervisor = new Supervisor("Guilhermina",<br /> "123456789", 3);<br />Employee employee = new Supervisor("Felisberto",<br /> "987654321", 5);<br />2009/2010<br />Programação Orientada por Objectos<br />7<br />
  8. 8. Sobreposição<br />Método de classe derivada pode sobrepor-se a método de classe base<br />Sobreposição é especialização<br />Regras<br />Mesma assinatura e tipo de devolução compatível<br />Método na classe base não privado e não final<br />Método na classe derivada com acessibilidade igual ou superior<br />2009/2010<br />Programação Orientada por Objectos<br />8<br />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.<br />Um método final não pode ser especializado.<br />
  9. 9. Categorias de acesso (de novo)<br />Características ou membros podem ser<br />private – acesso apenas por outros membros da mesma classe<br />package-private (sem qualificador) – adicionalmente, acesso por membros de classes do mesmo pacote<br />protected – adicionalmente, acesso por membros de classes derivadas<br />public – acesso universal<br />2009/2010<br />Programação Orientada por Objectos<br />9<br />Acessibilidade crescente<br />
  10. 10. Interfaces de uma classe<br />Própria classe<br />Membros da classe e membros não privados de classes base<br />Classe do mesmo pacote<br />Membros não privados da classe ou suas bases<br />Classe derivada<br />Membros protegidos ou públicos da classe ou suas bases<br />Outra classe<br />Membros públicos da classe ou suas bases<br />2009/2010<br />Programação Orientada por Objectos<br />10<br />
  11. 11. Exemplo<br />Vector<Employee> employees =<br /> new Vector<Employee>();<br />employees.add(new Employee("João Maria",<br /> "123456789"));<br />employees.add(new Supervisor("Ana Maria",<br /> "987654321", 4));<br />…<br />for (Employee employee : employees)<br /> out.println(employee.toString());<br />2009/2010<br />Programação Orientada por Objectos<br />11<br />Invocação da operação toString().<br />Qual o método toString() executado?<br />
  12. 12. Organização<br />2009/2010<br />Programação Orientada por Objectos<br />12<br />0<br />1<br />: Employee<br />: Supervisor<br />employees : «ref» Vector<Employee><br />: Vector<Employee><br />: «ref» Employee<br />: «ref» Employee<br />name = “João Maria”<br />ssn = “123456789”<br />name = “Ana Maria”<br />ssn = “987654321”<br />level = 4<br />Possível porque a classe Supervisor deriva da classe Employee, ou seja, possível porque um Supervisor é (sempre também) um Employee.<br />
  13. 13. Resultado<br />2009/2010<br />Programação Orientada por Objectos<br />13<br />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.<br />_<br />(João Maria, 123456789)<br />_<br />(João Maria, 123456789)<br />(Ana Maria, 987654321, 4)<br />_<br />
  14. 14. Polimorfismo<br />Capacidade de um objecto tomar várias formas<br />A forma descrita pela classe a que pertence<br />As formas descritas pelas classes acima na hierarquia a que pertence<br />Objecto pode ser referenciado por referências do tipo da classe a que pertence ou de classes acima na hierarquia (mais genéricas)<br />2009/2010<br />Programação Orientada por Objectos<br />14<br />
  15. 15. Princípio da substituição de Liskov<br />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 S é um subtipo de B.<br />Barbara H. Liskov e  Jeannette M. Wing, “A Behavioral Notion of Subtyping”, <br />ACM Transactions m Programming Languages and Systems, Volume 16, N.º 6, Novembro de 1994, pp. 1811-1841.<br />Ver http://en.wikipedia.org/wiki/Liskov_substitution_principle.<br />2009/2010<br />Programação Orientada por Objectos<br />15<br />Tem de ser o programador a garantir que este princípio se verifica!<br />
  16. 16. O que aparece na consola?<br />Supervisor supervisor = new Supervisor("Guilhermina", <br /> "123456789", 3);<br />Employee anEmployee = new Supervisor("Felisberto", <br /> "987654321", 5);<br />Employee anotherEmployee = new Employee("Elvira",<br /> "111111111");<br />out.println(supervisor.toString());<br />out.println(anEmployee.toString());<br />out.println(anotherEmployee.toString());<br />2009/2010<br />Programação Orientada por Objectos<br />16<br />_<br />(Guilhermina, 123456789, 3)<br />_<br />(Guilhermina, 123456789, 3)<br />(Felisberto, 987654321, 5)<br />_<br />(Guilhermina, 123456789, 3)<br />(Felisberto, 987654321, 5)<br />(Elvira, 111111111)<br />_<br />
  17. 17. Polimorfismo: operações e métodos<br />Uma operação polimórfica ou virtual pode ter várias implementações<br />A uma implementação de uma operação chama-se método<br />A uma operação polimórfica podem corresponder diferentes métodos, cada um em sua classe<br />Todas as operações em Java são polimórficas, com excepção das qualificadas com private<br />Uma classe é polimórfica se tiver pelo menos uma operação polimórfica<br />2009/2010<br />Programação Orientada por Objectos<br />17<br />
  18. 18. Polimorfismo: operações e métodos<br />Invoca-se uma operação sobre um objecto de uma classe para atingir um objectivo<br />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<br />Polimorfismo<br />Invocação de uma operação pode levar à execução de diferentes métodos<br />Método efectivamente executado depende da classe do objecto sobre o qual a operação é invocada<br />Método executadonão depende do tipo da referência para o objecto utilizado<br />2009/2010<br />Programação Orientada por Objectos<br />18<br />Simplificação… invocações internas podem levar à execução de métodos privados directamente.<br />
  19. 19. A classe Object<br />public class Employee extends Object {<br /> private String name;<br />   private String ssn;<br /> public Employee(final String name, final String ssn) {<br /> this.name = name;<br /> this.ssn = ssn;<br /> }<br /> public String getName() {<br /> return name;<br /> }<br /> public String getSsn() {<br /> return ssn;<br /> }<br /> @Override<br /> public String toString() {<br /> return "(" + getName() + ", " + getSsn() + ")";<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />19<br />Se uma classe não derivar explicitamente de outra, derivará implicitamente da classe Object, que está no topo da hierarquia de classes do Java.<br />Agora percebe-se! A classe Object declara a operação toString() e define imediatamente um correspondente método. Esta é uma sua especialização.<br />
  20. 20. Ligação estática vs. dinâmica<br />Ligação (binding)<br />Associação entre a invocação de uma operação e a execução de um método<br />Ligação estática <br />Operações não polimórficas, invocações através de super<br />Associação estabelecida em tempo de compilação<br />Ligação dinâmica<br />Operações polimórficas<br />Associação estabelecida apenas em tempo de execução<br />2009/2010<br />Programação Orientada por Objectos<br />20<br />Que é isto? Veremos à frente…<br />
  21. 21. Métodos finais<br />Classe derivada não é obrigada a fornecer método para operação da classe base<br />Classe base pode proibir às classes derivadas a sobreposição de um seu método, que se dirá ser um método final<br />Razão para um método ser final:<br />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<br />2009/2010<br />Programação Orientada por Objectos<br />21<br />
  22. 22. Uma ajudinha da classe base<br />public class Base {<br /> public String className() {<br /> return "Base";<br /> }<br />}<br />public class Derived extends Base {<br /> @Override<br /> public String className() {<br /> return “Derived”;<br /> }<br /> public void testCalls() {<br /> Base base = (Base)this;<br /> out.println("Through this: " + this.className());<br /> out.println("Through base: " + base.className());<br /> out.println("Through super: " + super.className());<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />22<br />_<br />Throughthis: Derived<br />_<br />Throughthis: Derived<br />Through base: Derived<br />_<br />Throughthis: Derived<br />Through base: Derived<br />Through super: Base<br />_<br />
  23. 23. Análise: conceitos<br />Veículo<br />Motociclo<br />Automóvel<br />Honda NX 650<br />Audi TT<br />2009/2010<br />Programação Orientada por Objectos<br />23<br />Vehicle<br />Motorcycle<br />Car<br />HondaNx650<br />AudiTt<br />Análise inicial pode resultar num dicionário ou glossário do domínio.<br />
  24. 24. Análise: relações<br />Um Automóvel é um Veículo<br />Um Motociclo é um Veículo<br />Uma Honda NX 650 é um Motociclo<br />Um Audi TT é um Automóvel<br />2009/2010<br />Programação Orientada por Objectos<br />24<br />Pode refinar-se o dicionário ou glossário do domínio, acrescentando as relações entre conceitos.<br />Vehicle<br />Car<br />Motorcycle<br />AudiTt<br />HondaNx650<br />
  25. 25. Desenho<br />2009/2010<br />Programação Orientada por Objectos<br />25<br />Vehicle<br />Propriedades<br />…<br />…<br />Operações<br />Car<br />Motorcycle<br />…<br />…<br />…<br />…<br />AudiTt<br />HondaNx650<br />…<br />…<br />…<br />…<br />
  26. 26. Implementação<br />public class Vehicle { <br /> …<br />}<br />public class Car extends Vehicle { <br /> …<br />}<br />public class Motorcycle extends Vehicle { <br /> …<br />}<br />public class HondaNx650 extends Motorcycle { <br /> …<br />}<br />public class AudiTt extends Car { <br /> …<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />26<br />
  27. 27. Conceitos abstractos e concretos<br />Conceito abstracto – Sem instâncias no domínio em causa<br />Conceito concreto – Com instâncias no domínio em causa<br />Conceitos identificados são abstractos ou concretos?<br />Dependendo do domínio e seu modelo… <br />Veículo e Automóvel abstractos; Audi TT concreto<br />Veículo abstracto; Automóvel e Audi TT concretos<br />2009/2010<br />Programação Orientada por Objectos<br />27<br />
  28. 28. Análise e desenho<br />Hipótese 1<br />Hipótese 2<br />2009/2010<br />Programação Orientada por Objectos<br />28<br />Vehicle<br />Vehicle<br />Car<br />Car<br />Motorcycle<br />Motorcycle<br />É boa prática que as classes concretas sejam folhas na hierarquia.<br />AudiTt<br />HondaNx650<br />As classes abstractas, correspondentes aos conceitos abstractos, têm o nome em itálico.<br />
  29. 29. Implementação: hipótese 1<br />public abstract class Vehicle { <br /> …<br />}<br />public class Car extends Vehicle { <br /> …<br />}<br />public class Motorcycle extends Vehicle { <br /> …<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />29<br />
  30. 30. Implementação: hipótese 2<br />public abstract class Vehicle { <br /> …<br />}<br />public abstract class Car extends Vehicle { <br /> …<br />}<br />public abstract class Motorcycle extends Vehicle { <br /> …<br />}<br />public class HondaNx650 extends Motorcycle { <br /> …<br />}<br />public class AudiTt extends Car { <br /> …<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />30<br />
  31. 31. Caixa de ferramentas: Position<br />public class Position {<br /> private double x;<br /> private double y;<br /> public Position(final double x, final double y) {<br /> this.x = x;<br /> this.y = y;<br /> }<br /> public final double getX() {<br /> return x;<br /> }<br /> public final double getY() {<br /> return y;<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />31<br />
  32. 32. Caixa de ferramentas: Size<br />public class Size {<br /> private double width;<br /> private double height;<br /> public Size(final double width,<br /> final double height) {<br /> this.width = width;<br /> this.height = height;<br /> }<br /> public final double getWidth() {<br /> return width;<br /> }<br /> public final double getHeight () {<br /> return height;<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />32<br />Apesar de ter também dois atributos do tipo double, um Size não é uma Position.<br />
  33. 33. Caixa de ferramentas: Box<br />public class Box {<br /> private Position topLeftCornerPosition;<br /> private Size size;<br /> public Box(final Position topLeftCornerPosition,<br /> final Size size) {<br /> this.topLeftCornerPosition = topLeftCornerPosition;<br /> this.size = size;<br /> }<br /> public final Position getTopLeftCornerPosition() {<br /> return position;<br /> }<br /> public final Size getSize() {<br /> return size;<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />33<br />Uma Box não é nem uma Position, nem um Size, mas é composta por uma Position e por um Size.<br />
  34. 34. Análise: conceitos<br />Figura<br />Forma (abstrato)<br />Círculo<br />Quadrado<br />2009/2010<br />Programação Orientada por Objectos<br />34<br />Figure<br />Shape<br />Circle<br />Square<br />
  35. 35. Análise: relações<br />Uma Figura é composta de Formas<br />Um Círculo é uma Forma<br />Um Quadrado é uma Forma<br />2009/2010<br />Programação Orientada por Objectos<br />35<br />Figure<br />Shape<br />Relação de composição.<br />Circle<br />Square<br />
  36. 36. Desenho<br />2009/2010<br />Programação Orientada por Objectos<br />36<br />Figure<br />Shape<br />…<br />…<br />…<br />…<br />Circle<br />Square<br />…<br />…<br />…<br />…<br />
  37. 37. Implementação<br />public class Figure {<br /> private Vector<Shape> shapes;<br /> …<br />}<br />public abstract class Shape { <br /> …<br />}<br />public class Circle extends Shape { <br /> …<br />}<br />public class Square extends Shape { <br /> …<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />37<br />
  38. 38. Implementação: Shape<br />public abstract class Shape {<br /> private Position position;<br /> public Shape(final Position position) {<br />this.position = position;<br /> }<br /> public final Position getPosition() {<br /> return position; <br /> }<br /> public abstract double getArea();<br /> public abstract double getPerimeter();<br /> public abstract Box getBoundingBox();<br /> public void moveTo(final Position newPosition) {<br /> position = newPosition;<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />38<br />Qual a área de uma “forma”??<br />Operações abstractas, ou seja, operações sem qualquer implementação disponível até este nível da hierarquia.<br />
  39. 39. Implementação: Circle<br />public class Circle extends Shape {<br /> private double radius;<br /> public Circle(final Position position,<br /> final double radius) {<br /> super(position);<br />this.radius = radius;<br /> }<br /> public final double getRadius() { <br /> return radius;<br /> }<br /> …<br />2009/2010<br />Programação Orientada por Objectos<br />39<br />Um Circle é uma Shape e a classe Circle herda a implementação da classe Shape.<br />É 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.<br />Uma ajudinha da classe base…<br />
  40. 40. Implementação: Circle<br /> …<br /> @Override<br /> public double getArea() {<br /> return Math.PI * getRadius() * getRadius();<br /> }<br /> @Override<br /> public double getPerimeter() {<br /> return 2.0 * Math.PI * getRadius();<br /> }<br /> @Override<br /> public Box getBoundingBox() {<br /> return new Box(<br /> new Position(getPosition().getX() - getRadius(),<br />getPosition().getY() - getRadius()),<br /> new Size(2.0 * getRadius(), 2.0 * getRadius())<br /> );<br /> }<br />}<br />2009/2010<br />Programação Orientada por Objectos<br />40<br />Qual a área de um círculo? Fácil, π×r2.<br />Fornece-se implementações, ou seja, métodos, para cada uma das operações abstractas da classe Shape.<br />
  41. 41. Desenho pormenorizado<br />2009/2010<br />Programação Orientada por Objectos<br />41<br />Shape<br />Figure<br />- position : Position <br />+ Shape(position : Position)<br />+ getPosition() : Position<br />+ getArea() : double<br />+ getPerimeter() : double<br />+ getBoundingBox() : Box<br />+ moveTo(newPosition : Position)<br />Circle<br />Square<br />- radius : double<br />+ Circle(position : Position, <br />radius : double)<br />+ getRadius() : double<br />+ getArea() : double<br />+ getPerimeter() : double<br />+ getBoundingBox() : Box<br />
  42. 42. Desenho pormenorizado<br />2009/2010<br />Programação Orientada por Objectos<br />42<br />Shape<br />Figure<br />- position : Position <br />«constructors»<br />+ Shape(position : Position)<br />«inspectors»<br />+ getPosition() : Position<br />+ getArea() : double<br />+ getPerimeter() : double<br />+ getBoundingBox() : Box<br />Circle<br />Square<br />- radius : double<br />«constructors»<br />+ Circle(position : Position, <br />radius : double)<br />«modifiers»<br />+ moveTo(newPosition : Position)<br />«inspectors»<br />+ getRadius() : double<br />+ getArea() : double<br />+ getPerimeter() : double<br />+ getBoundingBox() : Box<br />
  43. 43. Classes abstractas<br />Uma operação com qualificador abstract é uma simples declaração da operação<br />Uma operação sem qualificador abstract inclui também a definição de um método correspondente, que a implementa<br />Uma classe com uma operação abstracta tem de ser uma classe abstracta<br />Uma classe é abstracta se tiver o qualificador abstract<br />2009/2010<br />Programação Orientada por Objectos<br />43<br />
  44. 44. Classes abstractas<br />Uma classe não abstracta diz-se uma classe concreta<br />Uma classe abstracta não pode ser instanciada, i.e., não se podem construir objectos de uma classe abstracta<br />Uma classe derivada directamente de uma classe abstracta só poderá ser concreta se implementar cada uma das operações abstractas da classe abstracta<br />2009/2010<br />Programação Orientada por Objectos<br />44<br />
  45. 45. A reter...<br />Generalização – Relação entre duas classes, base e derivada, em que a derivada especializa a base, que por sua vez generaliza a derivada<br />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<br />Operação abstracta – Uma operações declarada numa dada classe mas não implementada nessa classe<br />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<br />2009/2010<br />Programação Orientada por Objectos<br />45<br />
  46. 46. A ler para as próximas aulas ...<br />Capítulos 1 a 10 e 16 do livro:<br />Y. Daniel Liang, Introduction to Java Programming, 7.ª edição, Prentice-Hall, 2008.ISBN: 978-0-13-605966-0<br />2009/2010<br />Programação Orientada por Objectos<br />46<br />
  47. 47. Sumário<br />Polimorfismo de subtipos<br />Classes e operações polimórficas<br />Herança<br />Ligação estática e ligação dinâmica<br />Classes abstractas e classes concretas<br />Operações abstractas<br />Análise, desenho e implementação<br />Dicionário do domínio<br />Conceitos<br />Conceitos concretos e conceitos abstractos<br />2009/2010<br />Programação Orientada por Objectos<br />47<br />

×