AULA 10 - Programação II - Graduação

De IFSC
Revisão de 12h57min de 18 de abril de 2018 por imported>Fargoud (→‎Sintaxe:)
Ir para navegação Ir para pesquisar

HERANÇA

Herança é um dos pontos chave de programação orientada a objetos (POO).

Ela fornece meios de promover a extensibilidade do código, a reutilização e uma maior coerência lógica no modelo de implementação.

Estas características nos possibilitam diversas vantagens, principalmente quando o mantemos bibliotecas para uso futuro de determinados recursos que usamos com muita frequência.

Uma classe de objetos "veiculo", por exemplo, contém todas as características inerentes aos veículos, como:

  • combustível,
  • autonomia,
  • velocidade máxima,
  • etc.

Agora podemos dizer que "carro" é uma classe que têm as características básicas da classe "veículo" mais as suas características particulares.

Analisando esse fato, podemos concluir que poderíamos apenas definir em "carro" suas características e usar "veículo" de alguma forma que pudéssemos lidar com as características básicas. Este meio chama-se herança.

Agora podemos definir outros tipos de veículos como:

  • moto,
  • caminhão,
  • trator,
  • helicóptero,
  • etc,

sem ter que reescrever a parte que está na classe "veículo". Para isso define-se a classe "veículo" com suas características e depois cria-se classes específicas para cada veículo em particular, declarando-se o parentesco neste instante.

Exemplo:

Imagine que já exista uma classe que defina o comportamento de um dado objeto da vida real, por exemplo, animal. Uma vez que eu sei que o leão é um animal, o que se deve fazer é aproveitar a classe animal e fazer com que a classe leão derive (herde) da classe animal as características e comportamentos que a mesma deve apresentar, que são próprios dos indivíduos classificados como animais.


PRGheranca1.png

Ou seja, herança acontece quando duas classes são próximas, têm características mútuas mas não são iguais e existe uma especificação de uma delas.

Portanto, em vez de escrever todo o código novamente é possível poupar algum tempo e dizer que uma classe herda da outra e depois basta escrever o código para a especificação dos pontos necessários da classe derivada (classe que herdou).


Através da herança, cria-se novas classes, chamadas de SUB-CLASSES ou CLASSES DERIVADAS, baseadas em uma classe já existente, chamada de SUPER-CLASSE ou CLASSE-BASE.

A classe derivada “herda” todas as características da classe-base, além de poder incluir suas características próprias.

Em resumo, o maior objetivo do uso do mecanismo de herança é a REUTILIZAÇÃO DE CÓDIGO, para facilitar o desenvolvimento e também para criação de BIBLIOTECAS.

É preciso ter o arquivo de código-objeto da super-classe (não o arquivo-fonte).



Sintaxe:

Para declarar uma classe derivada de outra já existente, procedemos de forma a declarar o parentesco e o grau de visibilidade (acesso) que a classe derivada terá dos membros de sua classe base.

Para isso seguimos o seguinte código sintático:


class NomeSubclasse: [Modificador de acesso] NomeSuperclasse
{  ...  
   //Características próprias da subclasse  
   ...
};

Exemplo:

Quando criamos um novo projeto no VC++, um formulário da classe Form1 é criado.

Esta classe é, na verdade, uma herança da classe mais geral Form:

class Form1 : public Form
{       
  ...
};

Implementação da classe derivada:

Existem algumas particularidades na implementação de uma subclasse:

Construtor da classe derivada

Pode utilizar o construtor da classe base. Exs:

class Quadrado : public Retangulo
{    public:
     Quadrado() :  Retangulo() { ...}
     Quadrado(int x1, int y1, int x2, int y2) : Retangulo(x1, y1, x2, y2) {...}
     ...   
};
class Quadrado : public Retangulo
{    public:
     Quadrado(int x1, int x2, int y1, int y2) 
    { 
            if(abs(x2 – x1) == abs(y2 – y1))
                Retangulo::Retangulo(x1, y1, x2, y2);
            else  
                 ShowMessage(“Coordenadas inválidas para quadrado”);
     ...  
};

Métodos da classe derivada também podem chamar métodos (públicos ou protegidos) da classe base usando a sintaxe

Classe_base::Método_classe_base( ); 

Se a classe derivada não possuir construtor – construtor da classe base é chamado.

Se este construtor da classe base não for default, ou não possuir valores default e não forem passados argumentos ⇒ ERRO!

Além de herança simples, uma classe pode ser derivada de mais de uma classe base ⇒ Herança múltipla!


Um método na classe derivada pode sobrecarregar um método da classe base : redefinir usando mesmo nome! Ex:

class Quadrado : public Retangulo
{    public:  // Métodos da classe base sobrecarregados na derivada:
        long int Calcula_Area( );
        long int Calcula_Perimetro( );
   ...
};
long int Quadrado::Calcula_Area( )
{   return(base*base);  }
long int Quadrado::Calcula_Perimetro()
{   return(4*base);       }

ESPECIFICADOR DE ACESSO PROTECTED:

As classes derivadas não têm acesso aos membros privados da classe base.

Para que as subclasses possam alterar atributos da superclasse, sem torná-los públicos: definí-los como protected.


Exemplo:

class Base { 	
       public: int publico; 
       private: int privado;
       protected: int protegido; 
};
class Derivada : public Base
{ public: int a, b, c;
  Derivada( ) {
           a = publico;   // Ok!
           b = protegido;   //Ok!
           c = privado; }   // ERRO! 
};  
PRGheranca.png

EXERCÍCIO:

A partir da classe Pessoa derive as classes:

  • Cliente - com o atributo particular CPF e o método privado ValidaCPF()*, e com os métodos de inicialização e atualização destes atributos;
  • Empregado - com os atributos particulares IdEmpresa, TotalVendas e Salario, os métodos de inicialização e atualização destes atributos, além de um método privado CalculaComissao( ).


* Número de inscrição no CPF

O número de inscrição no CPF é composto de onze dígitos decimais, sendo os oito primeiros aleatoriamente designados no momento da inscrição.

Já o nono (antepenúltimo) dígito indica a região fiscal responsável pela inscrição.

Por fim, o décimo e o décimo-primeiro são dígitos verificadores calculados de acordo com um algoritmo definido pela Receita Federal e publicamente conhecido.

Seja o código do CPF formado por

cpf[8] cpf[7] cpf[6] . cpf[5] cpf[4] cpf[3] . cpf[2] cpf[1] cpf[0] - v1 v2

A computação da expressão acima para o cálculo dos dígitos verificadores podem ser escritas de forma algorítmica tendo como base o seguinte pseudocódigo:

variáveis
 cpf[0..8]  vetor de Inteiros; 
 v1, v2: Inteiro;
início
 # popula a variável 'cpf' de forma inversa (o menor índice deve conter o dígito mais à direita do CPF)
 # ...
 para i := 0 até tamanho(cpf)-1 faça
   v1 := v1 + cpf[i] * (9 - (i mod 10));
   v2 := v2 + cpf[i] * (9 - ((i + 1) mod 10));
 fim-para
 v1 := (v1 mod 11) mod 10;
 v2 := v2 + v1 * 9;
 v2 := (v2 mod 11) mod 10;
 escreva(v1);
 escreva(v2);
fim.

Regiões fiscais brasileiras, indicadas pelo cpf[0]:

O terceiro dígito da direita para a esquerda identifica a unidade federativa na qual a pessoa foi registrada:

No exemplo CPF nº 000.000.00X-00

  • 0 - Rio Grande do Sul
  • 1 - Distrito Federal, Goiás, Mato Grosso do Sul e Tocantins
  • 2 - Pará, Amazonas, Acre, Amapá, Rondônia e Roraima
  • 3 - Ceará, Maranhão e Piauí
  • 4 - Pernambuco, Rio Grande do Norte, Paraíba e Alagoas
  • 5 - Bahia e Sergipe
  • 6 - Minas Gerais
  • 7 - Rio de Janeiro e Espírito Santo
  • 8 - São Paulo
  • 9 - Paraná e Santa Catarina

Mais informações:

  O código CPF - Wikipedia
e Valida Códigos