Post on 15-Dec-2018
Linguagem de Linguagem de Programação IProgramação IProgramação IProgramação I
Carlos Eduardo Batista
Centro de Informática - UFPBbidu@ci.ufpb.br
Carro
private:String modelo;String chassis;Motor m;
public:liga();
EncapsulamentoEncapsulamento e Composiçãoe Composição3
liga();acelera(int);freia(int);private:liberaCombustivel(int);freioABS(int);
� Hierarquia de classes
� Classes mais especializadas herdam das mais genéricas
� Atributos e métodos são herdados
� Classe filha é um “tipo de” Classe Pai
HerançaHerança4
� Herança simples
� Composição
� Combinando composição e herança
� Polimorfismo e funções virtuais
� Classes abstratas
� Herança múltipla (!!!)
Herança e composiçãoHerança e composição5
Polígono
Cor c;
desenhar();apagar();definirCor(Cor c);area();
Retângulo Triângulo
HerançaHerança6
Retângulo
desenhar();apagar();area();
desenhar();apagar();area();
Círculo
desenhar();apagar();area();
Animal
int idade;
come()dorme()
Ave
botaOvo()
Mamífero
mama()
Herança simplesHerança simples7
Cachorro
late()morde()
Curió
canta()voa()
� Utilização de objetos de classes existentescomo membros (atributos) de outrasclasses◦ A nova classe é composta de objetos de classes existentes Carro
Motor m;SistemaFreio f;Roda r[4];
ComposiçãoComposição8
Roda r[4];
anda()para()
Motor
acelera()
Roda
gira()
SistemaFreio
freia()
4
1
1
class Roda { };class Motor { };class SistemaFreio { };class Carro {vector <Roda> r;Motor m;SistemaFreio f;
ComposiçãoComposição9
SistemaFreio f;public: ...};
� Inicialização dos objetos é feita no construtor da classe que os contém
class Roda {double raio;
public:Roda(double r) : raio(r) {}
};
class Motor {double pot;
public:
class Carro {vector<Roda> rodas;Motor mot;SistemaFreio fre;
public:Carro (double r, double p, int n)
: rodas(4, Roda(r)) , mot(p), fre(n) {}};
ComposiçãoComposição10
public:Motor(double p): pot (p) { }
};
class SistemaFreio {int numSerie;
public:SistemaFreio(int n): numSerie(n) { }
};
int main() {Carro c1(10., 20., 234225);return 0;
}
� Novas classes podem ser formadasutilizando composição e herançaclass A {int i;
public:A(int ii) : i(ii) {}~A() {}void f() const {}
};
class C : public B {A a;
public:C(int ii) : B(ii), a(ii) {}~C() {} // chama ~B e ~Avoid f() const {
ComposiçãoComposição11
};class B {int i;
public:B(int ii) : i(ii) {}~B() {}void f() const {}
};
void f() const {a.f();B::f(); }};int main() {C c(47); }
� Ambas permitem reuso de código� Herança
◦ Características da classe base estão na interface da classe filha
◦ Classe filha é tipo da classe base� Subtipagem
� Composição◦ Classe contém as características das classes
HerançaHerança e/e/ouou composiçãocomposição
◦ Classe contém as características das classes utilizadas na composicão
◦ Essas características geralmente não aparecem na interface� Só se membro for público
12
� Herança privada◦ o que era público na classe base passa a ser privado na classe derivada
◦ A classe derivada é implementada em termos da classe base, e não é um tipo da classe base
◦ Pode-se expor alguns nomes na interface pública utilizando-se a palavra chave using
HerançaHerança privadaprivada13
class Pet {public:
char eat() const { return 'a'; }int speak() const { return 2; }float sleep() const { return 3.0; }float sleep(int) const { return 4.0; }
};class Goldfish : Pet { // Private inheritancepublic:
using Pet::eat; // Name publicizes memberusing Pet::sleep; // Both overloaded members expose d
};int main() {
HerançaHerança privadaprivada14
Goldfish bob;bob.eat();bob.sleep();bob.sleep(1);
//! bob.speak();// Error: private}
� Especificadores de acesso◦ public
◦ private
◦ protected
� Herança◦ Algo privado para os usuários da classe, mas acessível para os membros da própria
AtributosAtributos protegidosprotegidos
mas acessível para os membros da própriaclasse e de suas classes derivadas� Encapsulamento protected
15
include <fstream>using namespace std;class Base {
int i;protected:int read() const { return i; }
void set(int ii) { i = ii; }public:
Base(int ii = 0) : i(ii) {}int value(int m) const { return m*i; }
};
class Derived : public Base {int j;
AtributosAtributos protegidosprotegidos16
int j;public:
Derived(int jj = 0) : j(jj) {}void change(int x) { set(x); }
};int main() {Derived d;
d.change(10);}
� Quando se trabalha com herança pública, pode-se realizar upcasting
� A classe derivada é um tipo da classe base e um objeto instância da classe derivada pode ser utilizado como um da classe base quando necessário
PolimorfismoPolimorfismo17
void f(Animal &an) {an.come() ;an.dorme();
};void g(Ave &av) { f(av); }
� Upcast também pode ser realizado em ponteiros e referências, sem a necessidade de cast explícito
Ave av;Animal * an1 = & av;Animal & an2 = av;
PolimorfismoPolimorfismo18
an1-> come();an1->dorme();// an1->botaOvo(); // ERRO!!!
� E quando um método de Animal, por exemplo, Animal::come, é sobrescrito na classe Ave?
class Ave: public Animal {public:
void come( );void voa( );void botaOvo ( );
PolimorfismoPolimorfismo19
}...Ave av;Animal * an = &av;an-> dorme (); // Animal::dorme()an-> come (); // Animal::come()!
� O Polimorfismo provê outra dimensão de separação entre interface e implementação, desacoplando “o quê” de “como”, melhorando a organização do código gerado e o seu entendimento.
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais20
� Herança - classes e subclasses (subtipagem)
� Classes diferentes, derivadas de um mesmo tipo base, podem ser tratadas como se fossem de um único tipo
� Pode-se trabalhar com essas diferentes classes de maneira única
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais
classes de maneira única
� Cada classe poderá possuir uma maneira própria de tratar situações específicas
21
� Binding◦ Ligação entre objetos e funções
� Quando a ligação é efetuada antes da execução do programa ela é denominada de ligação estática (early binding)◦ Efetuada pelo compilador e pelo linker
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais22
� No exemplo, o compilador não consegue determinar a função a ser chamada◦ a única coisa que ele conhece é o tipo do ponteiro (Animal*) que está sendo utilizado
class Ave: public Animal {public:
void come( );void voa( );
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais23
void voa( );void botaOvo( );
}...Ave av;Animal * an = &av;an-> dorme (); // Animal::dorme()an-> come (); // Animal::come()!
� Solução: ligação dinâmica (late binding)◦ Ligação feita em tempo de execução
◦ Baseada no tipo do objeto apontado e não no tipo do ponteiro
� Em C++ funções ligadas dinamicamente devem ser declaradas como virtuais na classe base
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais
classe base
� Objetos devem ser manipulados por meio de referências para a classe base
24
� Somente a declaração da função necessita da palavra chave virtual
� O uso da palavra chave nas classes derivadas é redundante
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais25
class Animal {public:
virtual void come( );virtual void dorme( );
};class Ave: public Animal {public:
void come( );void voa( );void botaOvo ( );
int main() {Ave av;Animal an1;g(av); // OK: upcasting!g(an1); // OK!Animal * ptan = &av; //upptan-> dorme (); // Animal::dorme()ptan-> come (); // Ave::come()
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais26
void botaOvo ( );}
void g(Animal &an) {an.come();
}
// Ave::come()
return 0;}
� Polimorfismo◦ Funções homônimas para lógicas semelhantes ao longo de uma hierarquia
◦ Ligação dinâmica necessária para que haja polimorfismo
◦ Em C++, funções virtuais
� Classe base tem funções que devem ter
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais
� Classe base tem funções que devem ter comportamentos diferentes em suas derivadas◦ Funções virtuais na classe base
◦ Redefinidas nas classes derivadas
27
class Point { /* ... */};class Color{ /* ... */};enum Kind { circle,
triangle, square };class Shape {
Kind k;Point center;Color col;
public:void draw ( );
void Shape :: draw( ) {switch (k) {
case circle:// desenha o circulobreak;case triangle:// desenha o triangulobreak;case square:// desenha o quadrado
Já saber todos?
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais28
void draw ( );void rotate(float ang);
// ...};
// desenha o quadradobreak;} // end switch
}
Ruim
� Solução◦ Agrupar o que é comum a todas as subclasses em uma classe base� Ex. Shapes possuem uma forma, uma cor, podem ser desenhados, girados, etc.
◦ Propriedades e métodos específicos em classes derivadas� Ex. de triângulos, círculos e demais shapes
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais
� Ex. de triângulos, círculos e demais shapes
◦ Herança
29
class Shape {// ...public:
void draw( ) { cout << “Shape::draw”; }};class Triangle : public Shape {// ...public:
void draw( ) { cout << “Triangle::draw”;}};void teste( Shape & a) {
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais30
void teste( Shape & a) {a.draw();
}int main() {
Triangle t;teste(t); // Chamar de Shape, não de Triangle
}
class Shape{// ...virtual void draw( );
};class Triangle : public Shape {
// ...virtual void draw( ); // virtual é opcional
};void teste(Shape & a) {
a.draw();
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais32
}int main() {
Triangle t;teste(t); // Agora, chama draw de Triangle!
}
� Exercício:◦ Implementar exemplo Shapes
Polimorfismo e funções virtuaisPolimorfismo e funções virtuais33
� Notas de aula do Prof. Renato Maia (Unimontes)
� Notas de aula do Prof. Renato Mesquita (UFMG)
ReferênciasReferências35