Herança e composição
Herança simples
Composição
Combinando composição e herança
Polimorfismo e funções virtuais
Classes abstratas
Herança múltipla (!!!)
2
C++ e POO
Herança e composição em C++ ◦ Classes abstratas
◦ Herança múltipla
3
Encapsulamento e Composição 4
Carro
private: String modelo; String chassis; Motor m;
public: liga(); acelera(int); freia(int); private: liberaCombustivel(int); freioABS(int);
Herança
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
5
Herança 6
Polígono
Cor c;
desenhar(); apagar(); definirCor(Cor c); area();
Retângulo
desenhar(); apagar(); area();
Triângulo
desenhar(); apagar(); area();
Círculo
desenhar(); apagar(); area();
Herança simples 7
Animal
int idade;
come() dorme()
Ave
botaOvo()
Mamífero
mama()
Cachorro
late() morde()
Curió
canta() voa()
Herança privada
Herança privada ◦ o que era publico na classe base passa a ser privado na classe derivada
◦ A classe derivada é implementada em termos da classe base, e nao é um tipo da classe base
◦ Pode-se expor alguns nomes na interface publica utilizando-se a palavra chave using
8
Herança privada 9
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 inheritance
public:
using Pet::eat; // Name publicizes member
using Pet::sleep; // Both overloaded members exposed
};
int main() {
Goldfish bob;
bob.eat();
bob.sleep();
bob.sleep(1);
//! bob.speak();// Error: private
}
Atributos protegidos
Especificadores de acesso ◦ public
◦ private
◦ protected
Herança ◦ Algo privado para os usuarios da classe, mas acessivel para os membros da propria classe e de suas classes derivadas
Encapsulamento protected
10
Atributos protegidos 11
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;
public:
Derived(int jj = 0) : j(jj) {}
void change(int x) { set(x); }
};
int main() {
Derived d;
d.change(10);
}
Polimorfismo e funções virtuais
12
Polimorfismo e funções virtuais
13
class 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!
}
Herança 14
Classes abstratas
Classe abstrata é uma classe que não tem instâncias diretas ◦ Subclasses podem possuir instâncias
Classe concreta é uma classe instanciável
Método abstrato = método sem implementação (pure virtual) ◦ virtual void metodoAbstrato(...)=0;
15
Classes abstratas
Operações abstratas são definidas através de acoplamento dinâmico
Classes abstratas ◦ Obrigatoriamente não possuem instâncias e podem possuir métodos abstratos
A classe que define uma função virtual pura é uma classe abstrata pois não se pode declarar objetos dela.
Pode ser manuseada com ponteiros para manipular objetos de classes derivadas.
16
Classes abstratas 17
Classes abstratas 18
Classes abstratas 19
•#include <iostream>
•using namespace std;
•
•class Animal
•{
•public:
• virtual void comer() = 0;
• // Superclasses devem
• // ter o destrutor virtual
• virtual ~Animal()
• {
• }
•};
•
•class Lobo: public Animal
•{
•public:
• void comer()
• {
• cout << "Eu me alimento como um
lobo!" << endl;
• }
•};
•class Peixe: public Animal
•{
•public:
• void comer()
• {
• cout << "Eu me alimento como um
peixe!" << endl;
• }
•};
•
•int main(void)
•{
• Animal *a = new Lobo();
• Animal *b = new Peixe();
•
• a->comer();
• b->comer();
•
• return 0;
•}
Herança múltipla
A herança múltipla é a capacidade de uma classe derivada ter mais de uma classe base.
Permitir que que sejam definidas novas classes que herdem características de várias classes base (não relacionadas).
Reusabilidade ◦ Otimização o tempo de desenvolvimento
Organização ◦ Facilita o desenvolvimento e a interpretação na
manutenibilidade
20
Herança múltipla
A declaração do construtor de uma classe que é derivada de várias classes bases deve especificar os argumentos para as funções construtoras de todas as classes base
Pode ser manuseada com ponteiros para manipular objetos de classes derivadas.
21
Herança múltipla
A herança múltipla traz alguns novos problemas: ◦ Declaração de métodos de mesmo nome em duas superclasses distintas
Suponha dois métodos m() declarados tanto na classe
Vendedor quanto na Gerente ◦ Um objeto da Classe VendedorGerente que tenta invocar m() não saberia como fazer
◦ Indicar um caminho
22
Herança múltipla 23
Herança múltipla
No mesmo exemplo, haverá duas instâncias (ou objetos) da classe Empregado. Assim, um objeto da classe VendedorGerente não saberá qual deles utilizar ◦ indicar o caminho
◦ utilizamos a palavra virtual na herança
24
Herança múltipla 25
Herança múltipla 26
•class Knife
•{
•int d_blade;
•public:
•Knife(int blade):d_blade(blade){};
•int blade() const{ return d_blade; }
•void setBlade(int blade){ blade=blade;}
•};
•class CorkScrew
•{ int d_screw;
•public:
•CorkScrew(int screw):d_screw(screw){};
•int screw() const{ return d_screw; }
•void setScrew(int blade){ d_screw=screw;}
};
•class SwissKnife: public Knife, public
CorkScrew
•{ public:
•SwissKnife(int blade, int screw)
•: Knife(blade),CorkScrew(screw) {}
•}
•int main()
•{
• SwissKnife k(5,3);
• k.Knife::increase(2); // aumenta a lamina
• k.CorkScrew::increase(2);
•// aumenta o saca rolhas
• //SwissKnife k(5,3);
• Knife f(10);
• f=k; // possıvel, d_blade de f = 5
•}
Herança múltipla 27
•int lbs_weight(Vehicle const &v)
•// converte peso em libras
•{ return v.weight()*4.86;}
•int main()
•{
• Land l(1200, 130);
• Truck t(2600, 120, 6000);
• cout << lbs_weight(l) << "\n";
• << lbs_weight(t) << "\n";
•}
•Land l(1200, 130);
•Truck t(2600, 120, 6000);
•Vehicle *vp;
•vp = &l; // conv. implıcita para Vehicle
•vp = &t; // conv. implıcita para Vehicle
•Truck t(2600,120, 6000);
•Vehicle *vp;
vp = &t; // vp aponta para Truck
cout << pt->weight() << "\n"; // 2600
•Truck *pt;
•pt = reinterpret_cast<Truck *>(vp);
•cout << pt->weight() << "\n"; // 8600
•// Aqui a conversao (reinterpret
//cast<Truck*>)
•//transforma vp em Truck;
•//eh preciso ter cuidado,
•//só funciona se vp
•//apontar para um Truck;
Próximas aulas
Templates
Exceções ◦ (2ª. Prova e trabalho)
STL
Programação Orientada a Eventos
Programação concorrente (Threads) ◦ (3ª. Prova e trabalho)
28
Referências
Notas de aula do Prof. Renato Maia (Unimontes)
Notas de aula do Prof. Renato Mesquita (UFMG)
Notas de aula do Prof. Rodrigo Mello (USP)
http://www.rafaeltoledo.net
29