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

De IFSC
Revisão de 17h30min de 24 de agosto de 2017 por imported>Fargoud (→‎Exemplo:)
Ir para navegação Ir para pesquisar

Separando a interface da implementação

Conforme tudo que já foi descrito até o momento, o objetivo maior do encapsulamento de classes é preservar o sigilo acerca do código que vai ser implementado na classe.

Assim, é necessário que as classes sejam códigos independentes e fechados, que chamamos de IMPLEMENTAÇÃO DA CLASSE, compilados separadamente do restante do código-"cliente" (que serve de entrada/saída de dados com o usuário - INTERFACE COM O USUÁRIO), mas rodados juntos, linkados, para que funcionem conjuntamente.

O código-cliente vai ter acesso apenas aos Métodos e Atributos públicos dos objetos.

  • Métodos Públicos: são também chamados de INTERFACES DA CLASSE, pois serão usados diretamente pelos CLIENTES (programas usuários) para manipular os dados da classe.

A interface da classe normalmente é publicada na forma de Cabeçalhos (protótipos), em um arquivo de cabeçalho (*.h), fornecido junto com o executável da classe.

Separa1ii.png

Exemplo:

Separando os códigos de interface com o usuário da implementação da classe Horario:

Primeiro, em um arquivo *.h escreve-se a declaração da classe (INTERFACE DA CLASSE):

Arquivo de interface da classe

/* horario1.h  - Declaração da classe Horario      */
#ifndef HORARIO1_H
#define HORARIO1_H
class Horario 
{  public:
   Horario( );
   void SetaHora(int, int, int);
   void ImprimeMilitar( );
   void ImprimePadrao( );
   private:
       int hora, minuto, segundo;
 };
#endif
Separa3ii.png

Colocar inicialmente as diretivas como comentário, até que se tenha certeza que não há erros no código da classe.

Depois, em um arquivo *.cpp escreve-se a IMPLEMENTAÇÃO da classe, isto é, todos os códigos de seus métodos, principalmente os privados.

Arquivo de implementação da classe

/* horario1.cpp  - Definição dos métodos de Horario */
#include <iostream>
#include “horario1.h”
Horario::Horario( ) {hora=minuto=segundo = 0;}
void Horario::SetaHora(int h, int m, int s)
{   hora = (h>= 0 && h < 24)? h:0;
    minuto = (m>= 0 && m < 60)? m:0;
    segundo = (s>= 0 && h < 60)? s:0;  }
void Horario::ImprimeMilitar( );
{  cout << (hora < 10? “0”:”“) << hora << “:” << (minuto < 10?”0”:”“) << minuto;                                                                 
}
void Horario::ImprimePadrao( )
{ cout<<((hora==0 || hora==12)? 12:hora%12) << “:” << (minuto < 10?”0”:”“)<< minuto <<  “:” << (segundo < 10? ”0”:”“) << segundo <<  (hora<12? “da manhã”: “da tarde”);     }

Note que é imprescindível incluir-se o arquivo de cabeçalho, no arquivo de implementação.

Compilar estas unidades (horario1.h e horario1.cpp) em separado, p. e., em um aplicativo/Projeto comum que testa a classe.

Criar outro aplicativo, este sim o Cliente, e incluir o arquivo horario1.obj no projeto.

Acrescentar também a linha #include “horario1.h” aonde a classe for utilizada.

O Código-cliente pode desconhecer totalmente o conteúdo da implementação da classe.

Código-cliente da classe

/* IntImpl.cpp  - Aplicativo para testar a classe Horario */
#include <iostream>
#include “horario1.h”
int main()
{ Horario h;
  cout << “A hora militar inicial é: “ ; h.ImprimeMilitar( );
  cout << “\n  A hora padrão inicial é: “; h.ImprimePadrao( );       
  h.SetaHora(13,27,6); 
  cout <<“\n\n Nova hora militar: “; h.ImprimeMilitar( );
  cout << “\n  Nova hora padrão: “; h.ImprimePadrao( );       
  h.SetaHora(99,99,99);   //valores inválidos para h, m e s
  cout <<“\n\n Após inicialização inválida: \n Hora militar: “;
  h.ImprimeMilitar( );	cout << endl;
  return 0;
}

No Visual C++ 2008:

É necessário criar-se a classe clicando-se com o botão direito do mouse sobre o nome do projeto, no quadro Solution Explorer:

Separa2ii.png

Em seguida, o VC abre uma caixa para que vc escolha se quer criar uma classe comum (da linguagem C++), ou um componente para o próprio VC:

Separa4ii.png

Na sequência, é necessário dar-se um nome para esta classe e informar se ela é classe-filha, ou derivada, de outra classe.

Separa5ii.png

Note que o VC já cria outros arquivos junto com a classe.

E abre a janela de edição da interface da classe, arquivo *.h:

Separa6ii.png

e também a janela de edição da implementação da classe, que inicialmente só vai conter diretivas e um construtor vazio:

Separa7ii.png

Exemplo:

Classe exemplo que realiza cálculos matemáticos básicos para um código-cliente visual.


//ARQUIVO exemplo.h

#pragma once
ref class exemplo
{ private:
  int a, b, c;
  void SomaVals(void);
  void SubtraiVals(void);
  void MultiplicaVals(void);
  void DivideVals(void);
  void TipoOp(int);
 public:
  exemplo(void);
  void Lea(int);
  void Leb(int);
  int Devolve_saida(int);
 };

//ARQUIVO exemplo.cpp

#include "StdAfx.h"
#include "exemplo.h"
exemplo::exemplo(void)
{  }
void exemplo::Lea(int vala)
{ a = vala;  }
void exemplo::Leb(int valb)
{  b = valb;  }
void exemplo::SomaVals()
{  c = a + b;  }
int exemplo::Devolve_saida(int t)
{ TipoOp(t);
 return c;  }
void exemplo::TipoOp(int op)
{ switch(op)
  {case 1:  SomaVals();
   break;
   case 2: SubtraiVals();
   break;
   case 3:  MultiplicaVals();
   break;
   case 4: DivideVals();
   break;
  }
}
//
void exemplo::SubtraiVals(void)
{ 	 c = a - b;  }
//
void exemplo::MultiplicaVals(void)
{  c = a * b; }
//
void exemplo::DivideVals(void)
{ c = a/b;}

//CÓDIGO CLIENTE - arquivo Form1.h

#include "exemplo.h"
#pragma once
namespace separandoii {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
...
 public ref class Form1 : public System::Windows::Forms::Form
 {
    public:
    (...)
#pragma endregion
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
{   exemplo Objetoex;
    Objetoex.Lea(System::Convert::ToInt16(textBox1->Text));
    Objetoex.Leb(System::Convert::ToInt16(textBox2->Text));
    if(radioButton1->Checked == true) //Soma
    { label6->Text = "Somando valores";
      label5->Text = System::Convert::ToString(Objetoex.Devolve_saida(1));
    }else
      if(radioButton3->Checked == true) //Subtração
      { label6->Text = "Subtraindo valores";
        label5->Text = System::Convert::ToString(Objetoex.Devolve_saida(2));
      }else
         if(radioButton4->Checked == true) //Soma
        { label6->Text = "Multiplicando valores";
          label5->Text = System::Convert::ToString(Objetoex.Devolve_saida(3));
         }else
            if(radioButton5->Checked == true) //Subtração
            { label6->Text = "Dividindo valores";
              label5->Text=System::Convert::ToString(Objetoex.Devolve_saida(4));
            }else
                { label5->Text = "";
                  label6->Text = "Operação ainda indisponível!";
                 }
  }// fim button1_Click
 }; //fim classe Form1
} //fim projeto (namespace) separandoii

Exercícios:

Crie uma classe Aluno que contenha os atributos Nome, N_Matricula, Disciplinas e Medias. Este último é um vetor que conterá as notas médias do aluno, nas disciplinas (máximo de 10 por período). A declaração da classe (interface) deverá estar em um arquivo de cabeçalho. Projete também um Construtor e os métodos públicos Entra_Notas() e Imprime_Saida(), além do método privado Calcula_Medias(), em um arquivo de implementação. Por fim, utilize sua classe em um arquivo cliente, criando objetos a partir da mesma.

DICA: Utilize o componente TListBox, com os métodos Items->Add() e Items->Delete(), para inclusão/remoção de itens do quadro de lista.