Polimorfismo, Interfaces, Classes Abstractas: Difference between revisions
From Wiki**3
| (20 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
{{NAVPO}} | {{NAVPO}} | ||
{{TOCright}} | {{TOCright}} | ||
==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 | * Discussão de aspectos problemáticos | ||
==Exemplos== | ==Exemplos== | ||
* [[Exemplos Simples de Herança em Java | * [[Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Herança em Java|Exemplo simples]]: '''Animal''', '''Mamífero''', '''Gato''' | ||
* Editor gráfico sem classes abstractas | * [[Polimorfismo, Interfaces, Classes Abstractas/Editor gráfico sem classes abstractas|Editor gráfico sem classes abstractas]] | ||
* Editor gráfico com 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]] | * [[Classes Abstractas e Interfaces (Java)|Comparação entre classes abstractas e interfaces]] | ||
* [[Polimorfismo, Interfaces, Classes Abstractas | * [[Polimorfismo, Interfaces, Classes Abstractas/Exemplos Simples de Interfaces|Exemplos Simples de Interfaces]] em Java e C++ (classes virtuais puras) | ||
* [[Polimorfismo, Interfaces, Classes Abstractas | * [[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 50: | 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 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: | [[category:Ensino]] | ||
[[category: | [[category:PO]] | ||
Latest revision as of 14:10, 9 October 2018
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
- Exemplo simples: Animal, Mamífero, Gato
- Exemplos Simples de Interfaces em Java e C++ (classes virtuais puras)
- Exemplo com vários conceitos:
Cão,Vigilante,CãoDeGuarda,CãoPastor,Chihuahua,Robot,XP,XP2018(este exemplo tem vários "bugs")