Polimorfismo, Interfaces, Classes Abstractas: Difference between revisions

From Wiki**3

Root (talk | contribs)
No edit summary
 
Root (talk | contribs)
 
(38 intermediate revisions by the same user not shown)
Line 1: Line 1:
Material correspondente à Aula 09.
{{NAVPO}}
{{TOCright}}


==Tipos==
==Interfaces==


* Polimorfismo e tipos primitivos
* Princípios e propriedades
* Polimorfismo e tipos compostos (classes).
* Separação de interface e implementação
* Herança e polimorfismo: ''upcasting'' e ''downcasting''.


==Organização de Código==
== Noção de classe abstracta ==
* Propriedades
* Contraste com interfaces


* Definição de métodos: ''overloading'' vs. ''overriding''
== Abstracção, Polimorfismo ==
* Selecção do método a invocar: ''early binding'' e ''late binding''
 
O conceito de abstracção está relacionado com a capacidade de descrição de conceitos "abstractos", i.e., conceitos que descrevem múltiplos conceitos concretos. Em linguages OO, como Java ou C++, estes conceitos abstractos correspondem a classes abstractas (Java e C++), interfaces (Java; ou classes virtuais puras em C++), ou mesmo classes concretas não específicas (Animal, por exemplo, por oposição a Cão ou Gato). Nestas linguagens, existe ainda a possibilidade de abstracção genérica, i.e., definição de classes com dependência de tipos não especificados quando a classe é escrita. Estão neste caso, os ''generics'' do Java (e.g. '''ArrayList<Integer>''') e os ''templates'' do C++ (e.g. '''std::vector<int>''').
 
O conceito de polimorfismo corresponde à capacidade de referir objectos através de tipos que não o seu próprio ou de tipos genéricos. Quando se usam tipos genéricos, o polimorfismo consiste na manipulação dos objectos numa estrutura genérica (exemplos acima). Na presença de herança, i.e., quando existem hierarquias de classes, tem-se outro tipo de polimorfismo: o polimorfismo de inclusão. Este tipo de polimorfismo permite referir com tipos superiores na hierarquia objectos de tipos inferiores. O processo corresponde à definição de uma referência/ponteiro de um tipo superior que é utilizado para manipular um objecto de um tipo inferior.
 
Animal a = new Gato();  // upcasting (always safe) [Java]
 
As linguagens OO permitem este tipo de operação, pois um tipo mais abstracto é uma descrição resumida para um tipo mais concreto. Existe uma conversão implícita do tipo da referência concreta para o tipo da abstracta, designado por ''upcast''. Esta conversão é sempre segura, no sentido de o tipo superior é sempre uma descrição admissível para o tipo inferior (relação ''is-a''). No entanto, em C++, é possível controlar a sua utilização (herança privada, por exemplo). A conversão no sentido contrário (''downcast'') não é segura, pois um tipo superior pode referir vários inferiores que podem não estar relacionados entre si.
 
Além dos tipos de polimorfismo apresentados acima, e que são importantes para o desenho e implementação de aplicações OO, as linguagens modernas possuem ainda o polimorfismo associado aos tipos primitivos e que é, em geral, traduzido por conversões implícitas de tipo e representação em memória (int -> float, por exemplo).
 
As consequências para a programação são positivas: a abstracção e o polimorfismo permitem código para tipos menos específicos (ou mesmo genéricos) que é utilizável com tipos mais específicos (numa hierarquia de classes), ou concretos e definidos independentemente da classe (como é o caso dos genéricos -- note-se que podem existir algumas restrições pontuais). Em termos de gestão da produção de código, estes aspectos são importantes para a reutilização e desenvolvimento incremental.
 
== Definição de métodos: ''overloading'' vs. ''overriding'' ==
* Overloading: definição de métodos com o mesmo nome, mas com diferenças nos argumentos (tipo, número ou ambos) na mesma ou em classes relacionadas;
* Overriding: redefinição de um método definido anteriormente por uma das superclasses da hierarquia de uma classe.
* Overloading: '''Gato(int age) {...}''' e '''Gato(String name) {...}'''
* Overriding: redefinição por parte de '''Gato.respirar()''' de '''Animal.respirar()''' (sendo '''Gato''' uma subclasse de '''Animal''')
 
== Selecção do método a invocar ==
* ''early binding'' -- o método a invocar é conhecido em tempo de compilação (e.g., '''final''' em Java e não-'''virtual''' em C++)
* ''late binding'' -- o método a invocar é apenas conhecido em tempo de execução (habitual em Java; única possibilidade em PHP e outras linguagens semelhantes; e métodos declarados com '''virtual''' em C++)
 
== Outros aspectos ==
* Discussão de aspectos problemáticos


==Exemplos==
==Exemplos==


* [[PO 2005/06: Exemplos da Aula 09#Hierarquia de Classes|Exemplo simples]]: <code>Animal</code>, <code>Mamífero</code>, <code>Gato</code>
* [[Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Herança em Java|Exemplo simples]]: '''Animal''', '''Mamífero''', '''Gato'''
* [[PO 2005/06: Exemplos da Aula 09#Vector|Exemplo com vector]].
 
* [[Polimorfismo, Interfaces, Classes Abstractas/Editor gráfico sem classes abstractas|Editor gráfico sem classes abstractas]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Editor gráfico com classes abstractas|Editor gráfico com classes abstractas]]
 
* [[Classes Abstractas e Interfaces (Java)|Comparação entre classes abstractas e interfaces]]
 
* [[Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Interfaces|Exemplos Simples de Interfaces]] em Java e C++ (classes virtuais puras)
* [[Polimorfismo, Interfaces, Classes Abstractas/Exemplo com vários conceitos|Exemplo com vários conceitos]]: <code>Cão</code>, <code>Vigilante</code>, <code>CãoDeGuarda</code>, <code>CãoPastor</code>, <code>Chihuahua</code>, <code>Robot</code>, <code>XP</code>, <code>XP2018</code> (este exemplo tem vários "bugs")
 
== Exercícios ==
 
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 01: Energia, Predadores e Presas|Exercício 01: Energia, Predadores e Presas]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 02: Tabelas e Predicados|Exercício 02: Tabelas e Predicados]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 03: Carros e Motores|Exercício 03: Carros e Motores]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 04: Tabelas e Transformações|Exercício 04: Tabelas e Transformações]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 05: Tabelas e Impressoras|Exercício 05: Tabelas e Impressoras]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 06: Tabuleiros e Peças|Exercício 06: Tabuleiros e Peças]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 07: Fábrica e Empregados|Exercício 07: Fábrica e Empregados]]


[[category:PO 2005/2006]]
[[category:Ensino]]
[[category:PO]]

Latest revision as of 14:10, 9 October 2018

Programação com Objectos
Introduction
Creation and Destruction
Inheritance & Composition
Abstraction & Polymorphism
Code Organization
Java Topics
Inner Classes
Enumerations
Data Structures
Exceptions
Input/Output
RTTI
Other Topics
JUnit Tests
UML Topics
Design Patterns
"Simple" Factory
Composite & Visitor
Command
Strategy & State
Template Method
Observer
Abstract Factory
Decorator & Adapter
Façade (aka Facade)

Interfaces

  • Princípios e propriedades
  • Separação de interface e implementação

Noção de classe abstracta

  • Propriedades
  • Contraste com interfaces

Abstracção, Polimorfismo

O conceito de abstracção está relacionado com a capacidade de descrição de conceitos "abstractos", i.e., conceitos que descrevem múltiplos conceitos concretos. Em linguages OO, como Java ou C++, estes conceitos abstractos correspondem a classes abstractas (Java e C++), interfaces (Java; ou classes virtuais puras em C++), ou mesmo classes concretas não específicas (Animal, por exemplo, por oposição a Cão ou Gato). Nestas linguagens, existe ainda a possibilidade de abstracção genérica, i.e., definição de classes com dependência de tipos não especificados quando a classe é escrita. Estão neste caso, os generics do Java (e.g. ArrayList<Integer>) e os templates do C++ (e.g. std::vector<int>).

O conceito de polimorfismo corresponde à capacidade de referir objectos através de tipos que não o seu próprio ou de tipos genéricos. Quando se usam tipos genéricos, o polimorfismo consiste na manipulação dos objectos numa estrutura genérica (exemplos acima). Na presença de herança, i.e., quando existem hierarquias de classes, tem-se outro tipo de polimorfismo: o polimorfismo de inclusão. Este tipo de polimorfismo permite referir com tipos superiores na hierarquia objectos de tipos inferiores. O processo corresponde à definição de uma referência/ponteiro de um tipo superior que é utilizado para manipular um objecto de um tipo inferior.

Animal a = new Gato();  // upcasting (always safe) [Java]

As linguagens OO permitem este tipo de operação, pois um tipo mais abstracto é uma descrição resumida para um tipo mais concreto. Existe uma conversão implícita do tipo da referência concreta para o tipo da abstracta, designado por upcast. Esta conversão é sempre segura, no sentido de o tipo superior é sempre uma descrição admissível para o tipo inferior (relação is-a). No entanto, em C++, é possível controlar a sua utilização (herança privada, por exemplo). A conversão no sentido contrário (downcast) não é segura, pois um tipo superior pode referir vários inferiores que podem não estar relacionados entre si.

Além dos tipos de polimorfismo apresentados acima, e que são importantes para o desenho e implementação de aplicações OO, as linguagens modernas possuem ainda o polimorfismo associado aos tipos primitivos e que é, em geral, traduzido por conversões implícitas de tipo e representação em memória (int -> float, por exemplo).

As consequências para a programação são positivas: a abstracção e o polimorfismo permitem código para tipos menos específicos (ou mesmo genéricos) que é utilizável com tipos mais específicos (numa hierarquia de classes), ou concretos e definidos independentemente da classe (como é o caso dos genéricos -- note-se que podem existir algumas restrições pontuais). Em termos de gestão da produção de código, estes aspectos são importantes para a reutilização e desenvolvimento incremental.

Definição de métodos: overloading vs. overriding

  • Overloading: definição de métodos com o mesmo nome, mas com diferenças nos argumentos (tipo, número ou ambos) na mesma ou em classes relacionadas;
  • Overriding: redefinição de um método definido anteriormente por uma das superclasses da hierarquia de uma classe.
  • Overloading: Gato(int age) {...} e Gato(String name) {...}
  • Overriding: redefinição por parte de Gato.respirar() de Animal.respirar() (sendo Gato uma subclasse de Animal)

Selecção do método a invocar

  • early binding -- o método a invocar é conhecido em tempo de compilação (e.g., final em Java e não-virtual em C++)
  • late binding -- o método a invocar é apenas conhecido em tempo de execução (habitual em Java; única possibilidade em PHP e outras linguagens semelhantes; e métodos declarados com virtual em C++)

Outros aspectos

  • Discussão de aspectos problemáticos

Exemplos

Exercícios