Aula 8
Polimorfismo
1
protected
2

Acesso mais limitado que public

Acesso menos limitado que private

Membros com categoria de acesso
protected funcionam como private para
o público em geral, e como public para as
classes derivadas
2003/2004
Programação Orientada para
Objectos
protected
class A {
public:
A(int const a)
: a(a) {}
protected:
int a;
};
class B : public A {
public:
void mostra() const {
cout << a << endl;
}
};
3
2003/2004
Programação Orientada para
Objectos
Empregado…
class Empregado {
public:
Empregado(string const& nome,
Sexo const sexo);
string const& Empregado::nome() const
{
return nome_;
}
string const& nome() const;
Sexo sexo() const;
void mostra() const;
Sexo Empregado::sexo() const
{
return sexo_;
}
private:
string nome_;
Sexo sexo_;
};
Empregado::Empregado(string const& nome,
Sexo const sexo)
: nome_(nome), sexo_(sexo) {}
4
void Empregado::mostra() const
{
cout << “Nome: “ << nome() << endl
<< “Sexo: “ << sexo() << endl;
}
2003/2004
Programação Orientada para
Objectos
… e Chefe.
Classe derivada.
Chefe::mostra() oculta
Empregado::mostra().
é um
class Chefe : public Empregado {
public:
Chefe(string const& nome,
Sexo const sexo,
int const nível);
int nível() const;
void mostra() const;
private:
int nível_;
};
5
Classe base.
Chefe::Chefe(string const& nome,
Sexo const sexo,
int const nível)
: Empregado(nome, sexo),
nível_(nível) {}
int Chefe::nível() const
{
return nível_;
}
void Chefe::mostra() const
{
Empregado::mostra();
cout << “Nível: “ << nível() << endl;
}
2003/2004
Programação Orientada para
Objectos
Relação de generalização
Empregado
Atributos
e operações
omitidos.
Relação de
generalização.
Chefe
6
2003/2004
Programação Orientada para
Objectos
Herança pública

Classe derivada herda membros da classe base



Membros herdados mantêm categoria de acesso
Relação é um



Corte (slicing)
Ponteiros e referências do tipo da classe base podem-se
referir a objectos de classes derivadas!
Ocultação

7
Só é necessário definir o que é novo ou especializado
Classe derivada declara operação com mesmo nome de
uma existente na classe base.
2003/2004
Programação Orientada para
Objectos
Outras relações entre classes

Funciona como um, mas…

Herança privada


Tem um


Variável membro
Composição


Ser humano tem braços
Agregação

8
Membros herdados são privados
Ser humano tem relógio de pulso
2003/2004
Programação Orientada para
Objectos
Objectivo: tratar empregados e chefes
uniformemente
Problema: aparece tudo
como empregados!
list<Empregado*> pessoal;
pessoal.push_back(new Empregado(“João Maria”,masculino));
pessoal.push_back(new Chefe(“Ana Maria”, feminino, 4));
…
for(list<Empregado*>::iterador i = pessoal.begin();
i != pessoal.end();
++i)
(*i)->mostra();
Nome: João Maria
Sexo: masculino
…
for(list<Empregado*>::iterador i = pessoal.begin();
i != pessoal.end();
++i)
delete *i;
9
2003/2004
Nome: Ana Maria
Sexo: feminino
Programação Orientada para
Objectos
Objectos
pessoal: list<Empregado*>
!
10
: Empregado*
: Empregado*
: Empregado
: Chefe
nome_ = “João Maria”
sexo_ = masculino
nome_ = “Ana Maria”
sexo_ = feminino
nível_ = 4
2003/2004
!
Ligação.
Programação Orientada para
Objectos
Operações polimórficas
Classe polimórfica.
class Empregado {
public:
Empregado(string const& nome, Sexo const sexo);
string const& nome() const;
Sexo sexo() const;
virtual void mostra() const;
private:
string nome_;
Sexo sexo_;
Operação polimórfica
ou virtual.
};
11
2003/2004
Programação Orientada para
Objectos
Operações polimórficas
Classe polimórfica.
class Chefe : public Empregado {
public:
Chefe(string const& nome,
Sexo const sexo,
int const nível);
A assinatura tem de
ser exactamente
igual!
int nível() const;
virtual void mostra() const;
private:
int nível_;
};
12
2003/2004
Sobreposição: fornecimento
de um método especializado
para a classe derivada que
implementa a operação da
classe base.
Programação Orientada para
Objectos
Selecçção do método
depende do tipo do
objecto e não do tipo do
ponteiro.
Polimorfismo
list<Empregado*> pessoal;
pessoal.push_back(new Empregado(“João Maria”,masculino));
pessoal.push_back(new Chefe(“Ana Maria”, feminino, 4));
…
for(list<Empregado*>::iterador i = pessoal.begin();
i != pessoal.end();
++i)
(*i)->mostra();
Nome: João Maria
Sexo: masculino
…
for(list<Empregado*>::iterador i = pessoal.begin();
i != pessoal.end();
++i)
delete *i;
13
2003/2004
Nome: Ana Maria
Sexo: feminino
Nível: 4
Programação Orientada para
Objectos
Distinção entre operação e método

Operação


Método



14
Algo que se pode invocar para uma instância de uma
classe para atingir determinado objectivo
Implementação da operação para uma classe concreta
Invocação de uma operação leva à execução de um
método
Quando há polimorfismo, a invocação de uma
operação pode levar à execução de diferentes
métodos
2003/2004
Programação Orientada para
Objectos
Ligação estática vs. dinâmica

Ligação estática (operações não polimórficas)


Ligação dinâmica (operações polimórficas)

15
É o compilador que decide qual o método que é
executado quando se invoca a operação
Só durante a execução do programa é que se
sabe que método é executado, pois depende da
classe do objecto e não do ponteiro ou referência
2003/2004
Programação Orientada para
Objectos
Polimorfismo

Classe derivada não é obrigada a sobrepor versões
especializadas dos métodos da classe base:

Programador que desenhou classe base entende que
classes derivadas não devem fornecer métodos
especializados como implementação dessa operação

Invocação de operações polimórficas usa ligação
dinâmica

16
É menos eficiente que invocação de operações não polimórficas
2003/2004
Programação Orientada para
Objectos
Chefe com subordinados
class Chefe : public Empregado {
public:
Chefe(string const& nome, Sexo const sexo, int const nível);
int nível() const;
virtual void mostra() const;
void subordina(Empregado* const subordinado);
private:
int nível_;
list<Empregado*> subordinados;
};
void Chefe::subordina(Empregado* const subordinado)
{
subordinados.push_back(subordinado);
}
17
2003/2004
Programação Orientada para
Objectos
Chefe com subordinados
list<Empregado*> pessoal;
Empregado* pe = new Empregado("João Maria", masculino);
pessoal.push_back(pe);
Chefe* pc = new Chefe("Ana Maria", feminino, 4);
pc->subordina(pe);
pessoal.push_back(pc);
for(list<Empregado*>::iterator i = pessoal.begin(); i !=
(*i)->mostra();
…
pessoal.end(); ++i)
for(list<Empregado*>::iterator i = pessoal.begin(); i != pessoal.end(); ++i)
delete *i;
É invocado o destrutor de Empregado.
18
2003/2004
Programação Orientada para
Objectos
Destrutor virtual
class Empregado {
public:
Empregado(string const& nome, Sexo const sexo);
virtual ~Empregado() {}
Regra: se uma classe é base
de uma hierarquia de classes
polimórficas, tem de definir
um destrutor virtual!
string const& nome() const;
Sexo sexo() const;
virtual void mostra() const;
private:
string nome_;
Sexo sexo_;
};
19
Recomendação: Devem-se
explicitar sempre as operações
polimórficas (virtual).
2003/2004
Programação Orientada para
Objectos
Veículos

20
Conceitos relacionados

Um Automóvel é um Veículo

Um Motociclo é um Veículo

Uma Honda Dominator NX 650 é um Motociclo

Um Audi TT é um Automóvel
2003/2004
Programação Orientada para
Objectos
Veículos: implementação
class Veículo {
…
};
class Automóvel : public Veículo {
…
};
class Motociclo: public Veículo {
…
};
class HondaNX650 : public Motociclo {
…
};
class AudiTT : public Automóvel {
…
};
21
2003/2004
Programação Orientada para
Objectos
Veículos: representação
Conceitos
abstractos.
Veículo
Automóvel
Motociclo
Conceitos
concretos.
AudiTT
22
HondaNX650
2003/2004
Programação Orientada para
Objectos
Editor de figuras bidimensionais
class Posição {
public:
Posição(double const x,
double const y);
double x() const;
double y() const;
private:
double x_;
double y_;
};
class Dimensão {
public:
Dimensão(double const largura,
double const altura);
double largura() const;
double altura() const;
23
private:
double largura_;
double altura_;
};
class Caixa {
public:
Caixa(Posição const& posição,
Dimensão const& dimensão);
Posição const& posição() const;
Dimensão const& dimensão() const;
private:
Posição posição_;
Dimensão dimensão_;
};
2003/2004
Programação Orientada para
Objectos
Figuras e formas

Figura


Formas



24
list<Forma*> figura;
Conceito abstracto.
Quadrado
Círculo
…
Conceitos concretos.
2003/2004
Programação Orientada para
Objectos
Classe Forma
class Forma {
public:
Forma(Posição const& posição);
double área() const;
double perímetro() const;
Posição const& posição() const;
Caixa const caixaEnvolvente() const;
void movePara(Posicão const& nova_posição);
private:
Posição posição_;
};
25
2003/2004
Programação Orientada para
Objectos
Forma: métodos
Forma::Forma(Posição const& posição)
: posição_(posição)
{}
Caixa const Forma::
caixaEnvolvente() const
{
return ???;
}
double Forma::área() const
{
return ???;
}
void Forma::
movePara(Posição const& nova_posição)
{
posição_ = nova_posição;
}
double Forma::perímetro() const
{
return ???;
}
Posição const& Forma::posição() const
{
return posição_;
}
26
2003/2004
Programação Orientada para
Objectos
Classe Forma
class Forma {
public:
Forma(Posição const& posição);
virtual ~Forma() {}
virtual
virtual
Posição
virtual
Base de uma hierarquia
de classes polimórficas.
double área() const;
double perímetro() const;
const& posição() const;
Caixa const caixaEnvolvente() const;
virtual void movePara(Posicão const& nova_posição);
private:
Posição posição_;
};
27
2003/2004
Programação Orientada para
Objectos
Classe Círculo
class Círculo : public Forma {
public:
Círculo(Posição const& posição, double const raio);
virtual double área() const;
virtual double perímetro() const;
virtual Caixa const caixaEnvolvente() const;
double raio() const;
private:
double raio_;
};
28
Não é polimórfico:
não pode ser
especializado.
2003/2004
Programação Orientada para
Objectos
Círculo: métodos
double Círculo::área() const
{
return 2.0 * pi * raio();
}
Caixa const Círculo::
caixaEnvolvente() const
{
return
Caixa(Posição(posição().x() raio(),
posição().y() raio()),
Dimensão(2.0 * raio(),
2.0 * raio());
}
double Círculo::perímetro() const
{
return pi * raio() * raio();
}
double Círculo:: raio() const
{
return raio_;
}
Círculo::
Circulo(Posição const& posição,
double const raio)
: Forma(posição), raio_(raio)
{}
29
2003/2004
Programação Orientada para
Objectos
Classe abstracta Forma
class Forma {
public:
Forma(Posição const& posição);
virtual ~Forma() = 0;
virtual
virtual
Posição
virtual
Classe abstracta: classe
com operações abstractas.
Destrutor abstracto.
double área() const = 0;
double perímetro() const = 0;
const& posição() const;
Caixa const caixaEnvolvente() const = 0;
Operações
abstractas.
virtual void movePara(Posicão const& nova_posição);
private:
Posição posição_;
};
30
2003/2004
Programação Orientada para
Objectos
Forma: métodos
Forma::Forma(Posição const& posição)
: posição_(posição)
{}
Forma::~Forma()
{}
Apesar de abstracto,
o destrutor tem de ser
implementado.
Posição const& Forma::posição() const
{
return posição_;
}
void Forma::movePara(Posição const& nova_posição)
{
posição_ = nova_posição;
}
31
2003/2004
Programação Orientada para
Objectos
Forma
-posição_: Posição
«query» = inspector
«update» = modificador
«constructor»
+Forma(posição: Posição)
«query»
+área(): double
+perímetro(): double
+Posição(): Posição
+caixaEnvolvente(): Caixa
«update»
+movePara(nova_posição: Posição)
Quadrado
Classes abstractas
e operações
abstractas ou
puramente virtuais em
itálico.
Alternativamente
pode-se usar:
Forma {abstract}
Círculo
-raio_: double
«constructor»
+Círculo(posição: Posição, raio: double)
«query»
+área(): double
+perímetro(): double
+caixaEnvolvente(): Caixa
+raio(): double
Mais algumas notas...







33
Uma declaração de uma rotina membro indica a presença de uma
operação da classe
Uma definição de uma rotina membro indica a presença de um método
que implementa uma operação da classe
Uma operação abstracta não precisa de ser definida
Uma classe que declare uma operação abstracta, diz-se também uma
classe abstracta
Uma classe sem quaisquer operações abstractas é uma classe concreta
Uma classe derivada que herde das classes base operações abstractas,
só é concreta se fornecer métodos que implementem cada uma dessas
operações
Uma classe abstracta não pode ser instanciada
2003/2004
Programação Orientada para
Objectos
Aula 8: Sumário


Categorias de acesso: acesso protegido
Polimorfismo e operações polimórficas ou virtuais





Classes e operações abstractas



34
Operações polimórficas
Destrutores polimórficos
Ligação estática vs. dinâmica
Distinção entre operação e método
Operações abstractas ou puramente virtuais
Classes abstractas
Classes concretas
2003/2004
Programação Orientada para
Objectos
Download

Aula teórica - iscte-iul