Aula 6: Sobrecarga de
Operadores e Herança
Sobrecarga de Operadores Definição Relacionamentos Generalização/Especialização Vínculo Agregação Herança Definições Representação UML Exemplos (Direto/Indireto)Sobrecarga de Operador:
Definições
Sobrecarregar um operador significa redefinir seu
símbolo, de maneira que ele se aplique também a
tipos de dados definidos pelo usuário como classes e estruturas. (http://www.dimap.ufrn.br/~adilson/DIm327/transparencias/sobrecargaOperadores.PDF)
(http://www.coralinformatica.com.br/artigo07.php)
A implementação de sobrecarga de operadores é
definida por meio de funções chamadas operadoras , criadas como membro da classe ou como funções
Sob. Oper.: Limitações
Respeitar a definição original do operador
Não é possível mudar o operador de unário para binário
Não se pode inventar símbolos novos.
Não é possível modificar a precedência de operadores por meio de sobrecarga.
Não Sobrecarga de Operadores
Operadores que não podem ser
sobrecarregados:
. (operador ponto)
:: (operador de resolução de escopo) ? : (operador ternário)
Exemplo: Operador Unário 1
#include <iostream.h> #include <stdlib.h> class ponto { private : int x, y; public :ponto (int x1=0, int y1=0)
{
x=x1; y=y1;
Exemplo: Operador Unário 2
ponto operator ++( ) // função operadora pré-fixada {
++x; ++y;
return ponto(x, y); }
void printpt( ) const // imprime ponto {
cout << "(" << x << "," << y << ")"; }
Exemplo: Operador Unário 3
int main() {
ponto p1, p2(2,3), p3; // declara e inicializa cout << "\n p1 = " ;
p1.printpt( ); // imprime cout << "\n++p1 = " ;
(++p1).printpt( ); // incrementa e imprime
p3 = ++p2; // incrementa e atribui cout << "\n p3 = ";
p3.printpt( ); // imprime return 0;
Operador: Binário 1
Função Operadora com um argumento.
#include <iostream.h> #include <stdlib.h> class Ponto { public: int X, Y; Ponto(int aX = 0, int aY = 0) { X = aX; Y = aY; }
Operador: Binário
Ponto operator +(Ponto const aP) const; Ponto operator +=(int const aN);
bool operator ==(Ponto const aP) const;
}; class PFloat { public: float X, Y; PFloat(float aX = 0, float aY = 0) { X = aX; Y = aY; }
operator Ponto() const { return Ponto((int)X, (int)Y); } };
Ponto Ponto::operator +(Ponto const aP) const
{ return Ponto(X + aP.X, Y + aP.Y); }
Ponto Ponto::operator +=(int const aN)
{ X += aN; Y += aN;
return *this; }
bool Ponto::operator ==(Ponto const aP) const
{ return ((X == aP.X)&&(Y == aP.Y)); }
ostream & operator<<(ostream & OS, Ponto const aP)
Operador: Binário 3
int main(int argn, char ** argc) { Ponto P1, P2(2,3); PFloat Pf( 2.12, 3.14); P1 = Pf; // Conversao cout << "\n p1 = " << P1; cout << "\n p2 == p1 ? -> " << (P1 == P2); cout << "\n p2 = " << P2; cout << "\n p2 + p1 = " << (P2+P1); cout << "\n pf = " << Pf; // Conversao return 0; }
Acesso a serviços dos objetos:
Tipos Básicos
O uso dos identificadores como argumentos da
assinatura da função (mensagem)
O objeto solicitado tem um relacionamento
(agregação ou vínculo) com o outro objeto. Conferindo um ou mais identificadores aos outros objetos do relacionamento.
O serviço solicitado pertence a uma classe
Relacionamento: Conceitos
“Nenhum objeto é uma ilha”
Objetos são dependentes de outros
possibilitando o provimento de serviços.
Existem várias formas de interdependência dos
objetos como, por exemplo, alguns objetos são componentes de outros, ou são utilizados para unir outros objetos.
Essa interdependências são chamadas de
Relacionamento: Exemplo
(1) Funcionários no Domínio do trabalho (2) Fiscal no Domínio governamental
(3) Pais e filhos no Domínio familiar
Um fiscal (2) inspeciona as condições de trabalho dos funcionários (1), para assegurar a sua
integridade pessoal, procurando diminuir os conflitos domésticos (3).
Relacionamento: Tipos
importantes
Generalização/Especialização (cada um é
um Domínio Semântico)
Vínculos
Agregação
Generalização: Exemplo
A é um B? D G S C E Em R Diretor X S N N N N S Gerente Av X Av N N N S Supervisor N N X N N N S Consultor N N N X N N S Engenheiro N N N N X Av S Empreiteiro N N N N N X N Representante Av Av Av Av N N XGeneralização: Propriedades
1. Estruturais:
a) Atributos: O descendente terá todos os atributos do
ancestral
b) Relacionamentos de não Generalização. Exemplo: se for
acrescentado um vínculo (relacionamento entre dois
objetos) de casamento entre duas Pessoas, Funcionário também terá um vínculo de casamento porque ele é uma classe descendente de Pessoa.
2. Interface: Todos os serviços providos pelo ancestral
Generalização: Propriedades
4.
Comportamento:
a) Generalização sem Polimorfismo (bom
filho): Todos os métodos do ancestral utilizados em serviços, são também utilizados pelo filhos.
b) Generalização com Polimorfismo (mau
filho): Supressão de serviços
remanescentes do ancestral através dos descendentes que fornecem seus próprios métodos customizados, substituindo os
Generalização: Propriedades
4.
Matemáticas:
a) Anti-simetria: Se A é_um descendente de B, então B não pode ser de A.
b) Transitividade: Se um objeto A é_um objeto B e B é_um objeto C, então A é_um objeto C
Agregação: Conceitos
Objetos como sendo componentes de
Objetos.
Analistas e desenvolvedores estão
constantemente trabalhando com
entidades agregadas que consistem em
entidades de componentes.
Exemplo: Um pedido de compras é
Agregação: Propriedades
1. Estruturais:
As partes devem ter algum relacionamento estrutural ou funcional com o todo do qual elas sao
constituintes
2. Matemáticas:
a) Anti-simetria: Um pedido de compra não é parte de
um item de linha
b) Transitividade: Um Pedido de compra é composto
por itens, que por sua vez podem se compostos por subitens.
Herança: Conceitos
Uma característica importante da programação
orientada a objetos é permitir a criação de
novas classes com base em uma classe já
existente .
Objetivo: Proporcionar o reuso de software
“Herança é a capacidade de reusar código pela
especialização de soluções genéricas já
existentes”
Herança: Tipos
Subclasses herdam de superclasses
Superclasse direta - subclasse herda
explicitamente
Superclasse indireta - subclasse herda de dois
ou mais níveis superiores na hierarquia de classes
Herança: Notação UML
-Identidade : int … +cria(n:int) +insere(n: int) +imprimi() int Pai -Nome : String … +cria(n:int, d: String) +insere(n: int) +imprimi() int Filho Generalização http://dee.feg.unesp.br/Disciplinas/SEL3093/Herança: C++
#include <iostream.h> #include <string> #define TAM 80 using std::cout; using std::string;class BasAg // classe base {
protected :
char nome[TAM]; char numag[4];
Herança: C++
public : BasAg( ) { strcpy(nome,"Edward Norton"); strcpy(numag,"008"); } // ConstrutorBasAg( char n[ ], char ng[ ] ) { if ( strlen(n) < TAM ) strcpy(nome, n); if ( strlen(ng) < TAM ) strcpy(numag, ng); }// Construtor
Herança: C++
void print( )
{
cout << "\n\nDados do Agente : ";
cout << "\n ---";
cout << "\nNome : " << nome;
cout << "\nNumero : " << numag; }
Herança: C++
class Agente00 : public BasAg // classe derivada
{ protected: float altura; int idade; public : Agente() : BasAg() { altura = idade =0; }
Agente (char n[], char ng[], float a, int i)
: BasAg (n, ng)
{
altura = a; idade = i; }
Herança: C++
void print( ) {
BasAg::print();
cout << "\nAltura : " << altura; cout << "\nIdade : " << idade; }
Herança: C++
void main( ) {
Agente00 agente;
Agente00 agente2("James Bond", "007", 90, 40);
agente.print(); agente2.print(); }
Herança: Hierarquia
BasAg
Agente
Arma
Superclasse Direta de Agente Superclasse Indireta de Arma
Subclasse Direta de BasAg Superclasse Direta de Arma
Subclasse Direta de Agente Subclasse Indireta de BasAg
Herança: Direta/Indireta
class Arma : public Agente{ protected: string Nome; public: Arma() : Agente() { Nome.assign("Taurus 38"); }
Arma(char n[], char ng[], float a, int i, String gun) : Agente (n, ng, a, i) { Nome.assign(gun); }
void print( ) // mesmo nome da função membro de BasAg {
BasAg::print(); // chama print() da classe base Agente::print();
cout << "\nArma : " << Nome; } };
Herança: Direta/Indireta
void main( ) {
Agente agente;
Agente agente2("James Bond", "007", 90, 40); agente.print();
agente2.print();
Arma revolver("Michael Moore", "009", 210, 10, "Glock 35");
revolver.print(); }