Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Programação Orientada por Objectos - Aula 2

3,296 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
  • Be the first to comment

  • Be the first to like this

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 />

×