Polimorfismo, Interfaces, Classes Abstractas: Difference between revisions

From Wiki**3

Root (talk | contribs)
No edit summary
Root (talk | contribs)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{NAVPO}}
{{NAVPO}}
<!--{{TOCright}}-->
{{TOCright}}
Vários aspectos de polimorfismo:
 
* Polimorfismo e tipos primitivos
* Polimorfismo e tipos compostos (classes).
* Herança e polimorfismo: ''upcasting'' e ''downcasting''.
 
* 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++)


==Interfaces==
==Interfaces==
Line 18: Line 9:
== Noção de classe abstracta ==
== Noção de classe abstracta ==
* Propriedades
* Propriedades
* Contraste com interfaces


== Abstracção e Polimorfismo ==
== 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 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. Deste modo, estes últimos correspondem a polimorfismo na manipulação dos objectos numa estrutura genérica (exemplos acima). Outro tipo de polimorfismo, importante quando existem hierarquias de classes, é o polimorfismo de inclusão, que permite referir com tipos superiores na hierarquia objectos de tipos inferiores.
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 a 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.
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'' ==
== Definição de métodos: ''overloading'' vs. ''overriding'' ==
Line 33: Line 31:
* Overriding: redefinição por parte de '''Gato.respirar()''' de '''Animal.respirar()''' (sendo '''Gato''' uma subclasse de '''Animal''')
* Overriding: redefinição por parte de '''Gato.respirar()''' de '''Animal.respirar()''' (sendo '''Gato''' uma subclasse de '''Animal''')


=== Outros aspectos ===
== 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
* Discussão de aspectos problemáticos
* Contraste com interfaces


==Exemplos==
==Exemplos==
Line 47: Line 48:


* [[Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Interfaces|Exemplos Simples de Interfaces]] em Java e C++ (classes virtuais puras)
* [[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>XP2003</code>
* [[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 ==
== Exercícios ==
Line 56: Line 57:
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 04: Tabelas e Transformações|Exercício 04: Tabelas e Transformações]]
* [[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 05: Tabelas e Impressoras|Exercício 05: Tabelas e Impressoras]]
* [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 06: Tabuleiros e Paças|Exercício 06: Tabuleiros e Peças]]
* [[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:Ensino]]
[[category:Ensino]]
[[category:PO]]
[[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