Aula 8 Categorias de acesso: acesso protegido Polimorfismo e operações polimórficas ou virtuais Classes e operações abstractas 1 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 2002/2003 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) {} 2 void Empregado::mostra() const { cout << “Nome: “ << nome() << endl << “Sexo: “ << sexo() << endl; } 2002/2003 Programação Orientada para Objectos … e Chefe. 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_; }; 3 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; } 2002/2003 Programação Orientada para Objectos Operações polimórficas Operação polimórfica ou virtual 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_; }; 4 2002/2003 Sobreposição Programação Orientada para Objectos Distinção entre operação e método 5 Operação: algo que se pode invocar para uma instância de uma classe para atingir determinado objectivo Método: 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. 2002/2003 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) 6 É 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 2002/2003 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; void mostra() const; void subordina(Empregado* const subordinado); private: int nível_; list<Empregado*> subordinados; }; 7 2002/2003 Programação Orientada para Objectos Destrutor virtual class Empregado { public: Empregado(string const& nome, Sexo const sexo); virtual ~Empregado() {} string const& nome() const; Sexo sexo() const; void mostra() const; private: string nome_; Sexo sexo_; }; 8 2002/2003 Programação Orientada para Objectos Algumas regras... 9 Se uma classe é base de uma hierarquia de classes polimórficas, tem de definir um destrutor virtual Devem-se explicitar sempre as operações polimórficas (virtual) Uma classe derivada não é obrigada a sobrepor versões especializadas dos métodos da classe base 2002/2003 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; 10 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_; }; 2002/2003 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_; }; 11 2002/2003 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_; }; 12 2002/2003 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 double área() const = 0; double perímetro() const = 0; const& posição() const; Caixa const caixaEnvolvente() const = 0; virtual void movePara(Posicão const& nova_posição); private: Posição posição_; }; 13 2002/2003 Programação Orientada para Objectos Mais algumas regras... 14 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 2002/2003 Programação Orientada para Objectos pessoal: list<Empregado*> (! : Empregado* : Empregado nome_ = “João Maria” sexo_ = masculino : Empregado* !) : Chefe nome_ = “Ana Maria” sexo_ = feminino nível_ = 4 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