26
Programação Orientada a Objetos Renato Dourado Maia Universidade Estadual de Montes Claros Engenharia de Sistemas HERANÇA E COMPOSIÇÃO

Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

Programação Orientada a Objetos

Renato Dourado MaiaUniversidade Estadual de Montes Claros

Engenharia de Sistemas

HERANÇA E COMPOSIÇÃO

Page 2: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 2/26

Na Última Aula...

• Considere a definição de um tipo como Shape, a ser utilizado em um sistema gráfico. O sistema deve su-portar círculos, triângulos e quadrados:

class Point { /* ... */};class Color{ /* ... */};enum Kind { circle, triangle, square };class Shape {

Kind k; Point center;Color col;

public:void draw( );void rotate(float ang);// ...

};

void Shape :: draw( ){ switch (k) { case circle:

// desenha o circulo break; case triangle:

// desenha o triangulo break; case square:

// desenha o quadrado break; } // end switch}

Page 3: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 3/26

Na Última Aula...

• Problemas:– Funções como draw() precisam conhecer todos os tipos

de Shape que possam existir...– A função deve ser modificada toda vez que um novo Sha-

pe for adicionado ao sistema:✔ O código de draw é aumentado a cada inclusão de um Shape di-

ferente.✔ Na realidade, todas as funções que trabalham com shapes

terão que ser examinadas e modificadas!

Page 4: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 4/26

Na Última Aula...

• Problemas:– Um novo Shape poderá ser adicionado apenas no caso de

se ter acesso ao código fonte de todas as operações...– A parte de dados de Shape tem que ser escolhida de ma-

neira que acomode todas as possíveis representações de uma forma, seja ela qual for...

Page 5: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 5/26

Na Última Aula...

• Pensando na solução:– Uma saída está em se agrupar o que é comum a todas as

Shapes (elas possuem uma forma, uma cor, podem ser de-senhadas, giradas, etc) em uma classe, e as propriedades e métodos específicos de triângulos, círculos e demais shapes em classes derivadas:

✔ Isso já foi visto: herança!

Page 6: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 6/26

Na Última Aula...

• Pensando na solução:

Circ le

draw()

Square

draw()

Triangle

draw()()

Shape

draw()

Page 7: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 7/26

Na Última Aula...

• Problema da solução:– Seja o código a seguir:

class Shape {// ...public: void draw( ) { cout << “Shape::draw”; }};class Triangle : public Shape {// ...public: void draw( ) { cout << “Triangle::draw”;}};

void teste(Shape & a) { a.draw();}int main() { Triangle t; teste(t); // Vai chamar draw de Shape! E não de Triangle! }

Page 8: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 8/26

Na Última Aula...

E agora, quem poderá nos ajudar?

Page 9: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 9/26

O Chapolim Colorado?

O POLIMORFISMO É A SOLUÇÃO!

Page 10: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26

Polimorfismo – A Solução

• A solução anterior só funciona em C++ se forem in-troduzidas as funções virtuais, que adiam a ligação entre o objeto e a função chamada para o tempo de execução: – Isso permite o Polimorfismo...

Page 11: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 11/26

Polimorfismo – A Solução

Shape

<<virtual>> draw()

Circ le

<<virtual>> draw()

Square

<<virtual>> draw()

Triangle

<<virt ual>> draw()()

Page 12: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 12/26

Polimorfismo – A Soluçãoclass Shape{ // ... virtual void draw( );};class Triangle : public Shape { // ... virtual void draw( ); // virtual é opcional};

void teste(Shape & a) { a.draw();}int main() { Triangle t; teste(t); // Agora, chama draw de Triangle!}

Page 13: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 13/26

Polimorfismo – A Solução

• Sempre que o código original da função virtual na classe base não implementa a lógica que for deseja-da na classe derivada, basta implementar uma nova função, com o mesmo protótipo, na classe derivada.

Page 14: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 14/26

Tabela de Funções Virtuais

Como o programa pode fazer a ligação objeto/função em

tempo de execução?

Page 15: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 15/26

Tabela de Funções Virtuais

• Exemplo:class ClBase{ public: virtual void f1(int); virtual void f2(); int f3();};class ClDeriv : public ClBase { public: void f2(); int f3(); // Não deveria estar fazendo isso! virtual int f4(float);};

Page 16: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 16/26

Tabela de Funções Virtuais

TFV de ClBase

f1

f2

TFV de ClDeriv

f1

f2

f4

void ClBase :: f1(int) { ... }void ClBase :: f2() { ... }

void ClDeriv :: f2(int) { ... }void ClDeriv :: f4(float) { ... }

f3() não é virtual. Ela foi sobrecarregada em ClDeriv, mas não sepode identificar a chamada em tempo de execução, porque ela

não está na tabela de funções virtuais.

Page 17: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 17/26

Funções Virtuais

Por que não se escolheu fazer todas as funções virtuais

em C++?

Page 18: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 18/26

Funções Virtuais

• Em Java, todas as funções são virtuais. • Por que em C++ as funções não são automaticamen-

te virtuais, sendo necessário especificar aquelas para as quais se quer comportamento polimórfico?

Page 19: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 19/26

Funções Virtuais

• Questões associadas à eficiência do código:– Se não forem utilizadas funções virtuais, não haverá o o-verhead associado a elas:

✔ Tabela de funções virtuais, mais um ponteiro para a tabela por ob-jeto.

– Stroustrup:✔ “If you don’t use it, you don’t pay for it.”

– Se todas as funções fossem virtuais, não poderia existir o conceito de funções inline...

Page 20: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 20/26

Construtores e Destrutores

• Construtores não podem ser funções virtuais– Quando um objeto que contém funções virtuais é criado,

seu ponteiro para a tabela de funções virtuais precisa ser inicializado corretamente.

✔ Isso deve ser efetuado antes que haja a possibilidade de se cha-mar qualquer função virtual.

• Essa é uma atividade realizada pelo construtor: – O compilador (secretamente) insere código no início do

construtor para realizar essa tarefa.

Page 21: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 21/26

Construtores e Destrutores

• Lembre-se de que, quando se constrói um objeto de uma classe derivada, o construtor da classe base também é executado.

• Porém, podem-se chamar funções virtuais dentro dos construtores: – A função que será executada é correspondente à “parcela

do objeto” que está sendo construída naquele momento, ou seja, se a função é chamada dentro do construtor da classe base, a função virtual que será executada será a da classe base!

Page 22: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 22/26

Construtores e Destrutores

• Se o polimorfismo vai ser utilizado, os destrutores devem ser virtuais!

class Base { //Código com problema: destrutor de Base não virtual public : ~Base() {cout << "\n\tDestruindo a Parte da Base!";}};class Derivada : public Base { public : ~Derivada() {cout << "\n\tDestruindo a Parte da Derivada!";}};

int main() { Derivada deriv; Base * ptrBase = new Base; cout << "\nDeleta ObjBase : "; delete ptrBase; ptrBase = new Derivada; cout << "\nDeleta ObjDeriv : "; delete ptrBase; return 0; }

Resultado problemático:Deleta ObjBase : Destruindo a Parte da Base!Deleta ObjDeriv : Destruindo a Parte da Base! Destruindo a Parte da Derivada! Destruindo a Parte da Base!

Page 23: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 23/26

Construtores e Destrutores

• Se o polimorfismo vai ser utilizado, os destrutores devem ser virtuais:– Se forem alocados objetos da classe derivada a partir de

ponteiros da classe base com destrutores não virtuais, somente o destrutor da Parte Base é chamado, apesar de ptrBase estar apontando, no segundo caso, para um obje-to da classe Derivada.

• Repetindo: o destrutor deve ser virtual para que o comportamento seja como o esperado.

Page 24: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 24/26

Construtores e Destrutores

• Se o polimorfismo vai ser utilizado, os destrutores devem ser virtuais!class Base { public : virtual ~Base() {cout << "\n\tDestruindo a Parte da Base!";}};

int main() { Derivada deriv; Base * ptrBase = new Base; cout << "\nDeleta ObjBase : "; delete ptrBase; ptrBase = new Derivada; cout << "\nDeleta ObjDeriv : "; delete ptrBase; return 0; }

Resultado:Deleta ObjBase : Destruindo a Parte da Base!Deleta ObjDeriv : Destruindo a Parte da Derivada! Destruindo a Parte da Base! Destruindo a Parte da Derivada! Destruindo a Parte da Base!

Page 25: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 25/26

Importante

• Esta apresentação é uma adaptação do material ori-ginalmente desenvolvido pelo professor Renato Car-doso Mesquita, do Departamento de Engenharia Elé-trica da Universidade Federal de Minas Gerais.

http://www.cpdee.ufmg.br/~renato

Page 26: Programação Orientada a Objetos · 2015-08-24 · 24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 10/26 Polimorfismo – A Solução • A solução anterior

24/08/15 Programação Orientada a Objetos – Renato Dourado Maia 26/26

That's All Folks!