Desenvolvimento - Visual Basic .NET

POO – Programação Orientada a Objetos – Parte 2

Vamos ver na prática como utilizar a Programação Orientada a Objetos utilizando como referência o artigo POO – Programação Orientada a Objetos Parte 1.

por David Pomarico



Vamos ver na prática como utilizar a Programação Orientada a Objetos utilizando como referência o artigo POO – Programação Orientada a Objetos Parte 1.

Situação:

Elaborar um Cadastro de Clientes. Os dados serão incluídos em um banco de dados Access 2000.

Diagrama de Classes

Criando as Classes e adicionando funcionalidades

Cliente

Adicionamos dois atributos private para a classe de Cliente, um método chamado Gravar e outro chamado Retornar. Agora vamos adicionar as Property para retornar ou setar o valor dos atributos, utilizando assim o encapsulamento de atributos.

    Private _cliCodigo As Integer
    Public Property cliCodigo() As Integer
        Get
            Return _cliCodigo
        End Get
        Set(ByVal Value As Integer)
            _cliCodigo = Value
        End Set
    End Property


    Private _cliNome As String
    Public Property cliNome() As String
        Get
            Return _cliNome
        End Get
        Set(ByVal Value As String)
            _cliNome = Value
        End Set
    End Property

    Private _cliTelefone As String
    Public Property cliTelefone() As String
        Get
            Return _cliTelefone
        End Get
        Set(ByVal Value As String)
            _cliTelefone = Value
        End Set
    End Property

Feito isso, devemos implementar o método Gravar e Retornar da classe de clientes. Porém, sabemos que existem dois tipos de clientes, Pessoa Física e Pessoa Jurídica. Então como vamos Gravar ou Retornar um cliente sem os atributos que estão nas classes derivadas?

Para tal procedimento devemos fazer algumas alterações:

  • Adicionar a palavra MustInherit na classe clsCliente, indicando que esta classe tem de ser herdada.
  • Adicionar a palavra Overridable indicando que podemos sobrepor o método Gravar() da classe.
  • Adicionar a palavra Overridable indicando que podemos sobrepor o método Retornar() da classe.
  • Adicionar o método Construtor de nossa classe.
  • Adicionar o método Construtor fazendo uma sobrecarga.

Assim ficará nossa classe clsCliente:

Public MustInherit Class clsCliente

    Private _cliCodigo As Integer
    Public Property cliCodigo() As Integer
        Get
            Return _cliCodigo
        End Get
        Set(ByVal Value As Integer)
            _cliCodigo = Value
        End Set
    End Property


    Private _cliNome As String
    Public Property cliNome() As String
        Get
            Return _cliNome
        End Get
        Set(ByVal Value As String)
            _cliNome = Value
        End Set
    End Property


    Private _cliTelefone As String
    Public Property cliTelefone() As String
        Get
            Return _cliTelefone
        End Get
        Set(ByVal Value As String)
            _cliTelefone = Value
        End Set
    End Property

    Public Overridable Sub Gravar()

    End Sub

    Public Overridable Function Retornar() As DataSet

    End Function


    Public Sub New()

    End Sub

 
    Public Sub New(ByVal Codigo As Integer, ByVal Nome As String, ByVal Telefone As String)
        cliCodigo = Codigo
        cliNome = Nome
        cliTelefone = Telefone
    End Sub

End Class
Pessoa Física

Devemos fazer o mesmo que a classe de cliente, adicionar os atributos e métodos. Criaremos dois Contrutores New para fazer a sobrecarga.

Veja como ficou nossa classe clsPessoaFisica:

Public Class clsPessoaFisica

    Inherits clsCliente

    Private _pefCPF As String
    Public Property pefCPF() As String
        Get
            Return _pefCPF
        End Get
        Set(ByVal Value As String)
            _pefCPF = Value
        End Set
    End Property


    Private _pefRG As String
    Public Property pefRG() As String
        Get
            Return _pefRG
        End Get
        Set(ByVal Value As String)
            _pefRG = Value
        End Set
    End Property

 
    Public Sub New()

    End Sub

 
    Public Sub New(ByVal CPF As String, ByVal RG As String)
        pefCPF = CPF
        pefRG = RG
    End Sub

End Class

Vamos implementar o método Gravar de Pessoa Física. Para isso devemos utilizar os atributos da classe pai e da classe filha para que possamos gravar os dados do cliente. Note que devemos adicionar a palavra Overrides que indica que iremos sobrepor o método Gravar() da classe pai.

Public Overrides Sub Gravar()
        Dim strConexao As String = System.Configuration.ConfigurationSettings.AppSettings("Conexao")
        "Declaro a conexao
        Dim con As New OleDbConnection(strConexao)
        "Declaro um objeto OleDbCommand
        Dim cmd As New OleDbCommand

        "Este é o modo que declaro meus paramentros. Faça do jeito que achar melhor.
        Dim prmParametro = New OleDbParameter(3) {}
        prmParametro(0) = New OleDbParameter("@cliNome", MyBase.cliNome)
        prmParametro(1) = New OleDbParameter("@cliTelefone", MyBase.cliTelefone)
        prmParametro(2) = New OleDbParameter("@pefCPF", pefCPF)
        prmParametro(3) = New OleDbParameter("@pefRG", pefRG)
        "Monto a string de SQL para inserir no banco
        Dim strSQL As New Text.StringBuilder
        strSQL.Append("insert into tblCliente ")
        strSQL.Append("(cliNome, cliTelefone, cliCPF, cliRG) ")
        strSQL.Append("values ")
        strSQL.Append("(@cliNome, @cliTelefone, @cliCPF, @cliRG)")

        "Adiciono os parametros no meu objeto OleDbCommand
        Dim p As OleDbParameter
        For Each p In prmParametro
            cmd.Parameters.Add(p)
        Next

        Try
            "Abre conexao
            con.Open()
            "Seta a conexao
            cmd.Connection = con
            "Defino o tipo de Command.
            cmd.CommandType = CommandType.Text
            "Passo o comando a ser executado.
            cmd.CommandText = strSQL.ToString
            "Executo
            cmd.ExecuteNonQuery()
        Catch OleDbEx As OleDbException
            Throw New Exception(OleDbEx.Message)
        Catch ex As Exception
            Throw New Exception(ex.Message)
        Finally
            If Not IsNothing(cmd) Then
                cmd.Dispose()
            End If
            If con.State <> ConnectionState.Closed Then
                con.Close()
                con.Dispose()
            End If
        End Try

    End Sub

Agora vamos implementar o método que irá retornar os dados de clientes do tipo Pessoa Física. Fiz um método bem simples somente para demonstração.

     Public Overrides Function Retornar() As DataSet
        Dim strConexao As String = System.Configuration.ConfigurationSettings.AppSettings("Conexao")
        "Declaro a conexao
        Dim con As New OleDbConnection(strConexao)
        "Declaro um objeto OleDbCommand
        Dim cmd As New OleDbCommand

        "Monto a string de SQL para inserir no banco
        Dim strSQL As New Text.StringBuilder
        strSQL.Append("SELECT cliCodigo, cliNome, ")
        strSQL.Append("cliTelefone, cliCPF, cliRG ")
        strSQL.Append("FROM tblCliente WHERE cliCNPJ IS NULL;")
        cmd.Connection = con
        cmd.CommandType = CommandType.Text
        cmd.CommandText = strSQL.ToString()

        Dim da As New OleDbDataAdapter(cmd)
        Dim ds As New DataSet
        Try
            "Abre conexao
            con.Open()
            "Preencho o DataSet com os dados
            da.Fill(ds)
        Catch OleDbEx As OleDbException
            Throw New Exception(OleDbEx.Message)
        Catch ex As Exception
            Throw New Exception(ex.Message)
        Finally
            If Not IsNothing(cmd) Then
                cmd.Dispose()
            End If
            If con.State <> ConnectionState.Closed Then
                con.Close()
                con.Dispose()
            End If
        End Try

        Return ds

    End Function
Pessoa Jurídica

Devemos fazer o mesmo que a classe de Pessoa Física, porém o que vai ser diferente é a forma de implementação do método Gravar(), Retornar() e os construtores da classe.

Veja como ficará nossa classe de Pessoa Jurídica:

Public Class clsPessoaJuridica
    Inherits clsCliente


    Private _pejCNPJ As String
    Public Property pejCNPJ() As String
        Get
            Return _pejCNPJ
        End Get
        Set(ByVal Value As String)
            _pejCNPJ = Value
        End Set
    End Property

    Private _pejInscricaoEstadual As String
    Public Property pejInscricaoEstadual() As String
        Get
            Return _pejInscricaoEstadual
        End Get
        Set(ByVal Value As String)
            _pejInscricaoEstadual = Value
        End Set
    End Property

    Private _pejNomeFantasia As String
    Public Property pejNomeFantasia() As String
        Get
            Return _pejNomeFantasia
        End Get
        Set(ByVal Value As String)
            _pejNomeFantasia = Value
        End Set
    End Property

    Public Sub New()

    End Sub

    Public Sub New(ByVal CNPJ As String, ByVal NomeFantasia As String, ByVal InscricaoEstadual As String)
        pejCNPJ = CNPJ
        pejNomeFantasia = NomeFantasia
        pejInscricaoEstadual = InscricaoEstadual
    End Sub

    Public Overrides Sub Gravar()
        Dim strConexao As String = System.Configuration.ConfigurationSettings.AppSettings("Conexao")
        "Declaro a conexao
        Dim con As New OleDbConnection(strConexao)
        "Declaro um objeto OleDbCommand
        Dim cmd As New OleDbCommand

        "Este é o modo que declaro meus paramentros. Faça do jeito que achar melhor.
        Dim prmParametro = New OleDbParameter(4) {}

        prmParametro(0) = New OleDbParameter("@cliNome", MyBase.cliNome)
        prmParametro(1) = New OleDbParameter("@cliTelefone", MyBase.cliTelefone)
        prmParametro(2) = New OleDbParameter("@pejCPNPJ", pejCNPJ)
        prmParametro(3) = New OleDbParameter("@pejNomeFantasia", pejNomeFantasia)
        prmParametro(4) = New OleDbParameter("@pejInscricaoEstadual", pejInscricaoEstadual)

        "Monto a string de SQL para inserir no banco
        Dim strSQL As New Text.StringBuilder
        strSQL.Append("insert into tblCliente ")
        strSQL.Append("(cliNome, cliTelefone, cliCNPJ, cliInscricaoEstadual, cliNomeFantasia) ")
        strSQL.Append("values ")
        strSQL.Append("(@cliNome, @cliTelefone, @cliCNPJ, @cliInscricaoEstadual, @cliNomeFantasia)")

        "Adiciono os parametros no meu objeto OleDbCommand
        Dim p As OleDbParameter
        For Each p In prmParametro
            cmd.Parameters.Add(p)
        Next

        Try
            "Abre conexao
            con.Open()
            "Seta a conexao
            cmd.Connection = con
            "Defino o tipo de Command.
            cmd.CommandType = CommandType.Text
            "Passo o comando a ser executado.
            cmd.CommandText = strSQL.ToString
            "Executo
            cmd.ExecuteNonQuery()
        Catch OleDbEx As OleDbException
            Throw New Exception(OleDbEx.Message)
        Catch ex As Exception
            Throw New Exception(ex.Message)
        Finally
            If Not IsNothing(cmd) Then
                cmd.Dispose()
            End If
            If con.State <> ConnectionState.Closed Then
                con.Close()
                con.Dispose()
            End If
        End Try

    End Sub

    Public Overrides Function Retornar() As DataSet
        Dim strConexao As String = System.Configuration.ConfigurationSettings.AppSettings("Conexao")
        "Declaro a conexao
        Dim con As New OleDbConnection(strConexao)
        "Declaro um objeto OleDbCommand
        Dim cmd As New OleDbCommand

        "Monto a string de SQL para inserir no banco
        Dim strSQL As New Text.StringBuilder

        strSQL.Append("SELECT cliCodigo, cliNome, ")
        strSQL.Append("cliTelefone, cliNomeFantasia,  ")
        strSQL.Append("cliInscricaoEstadual, cliCNPJ ")
        strSQL.Append("FROM tblCliente WHERE cliCPF IS NULL;")
        cmd.Connection = con
        cmd.CommandType = CommandType.Text
        cmd.CommandText = strSQL.ToString()

        Dim da As New OleDbDataAdapter(cmd)
        Dim ds As New DataSet
        Try
            "Abre conexao
            con.Open()
            "Preencho o DataSet com os dados
            da.Fill(ds)
        Catch OleDbEx As OleDbException
            Throw New Exception(OleDbEx.Message)
        Catch ex As Exception
            Throw New Exception(ex.Message)
        Finally
            If Not IsNothing(cmd) Then
                cmd.Dispose()
            End If
            If con.State <> ConnectionState.Closed Then
                con.Close()
                con.Dispose()
            End If
        End Try

        Return ds

    End Function

End Class
Pergunta
Preciso montar uma function que irá retornar um DataSet. Porém eu preciso passar parâmetros para um objeto do tipo Command. E agora como eu faço?

Resposta
Simples. Pergunte sempre se você irá precisar do objeto preenchido para fazer tal procedimento. Se a resposta for sim, utilize o método New que irá lhe retornar um objeto preenchido. Caso a resposta seja não, utilize o método como Shared e chame o método que irá retornar o DataSet passando o parâmetro necessário através de ByVal ou ByRef. Ficaria assim:

Deste modo eu não preciso alocar o objeto na memória e com isso reduzirei a utilização da mesma.

Agora vamos criar dois formulários para podermos utilizar as classes criadas. Um formulário será o de cadastro de cliente e o outro para pesquisar clientes (sem filtro). Criei o formulário de cadastro de cliente com 2 groupbox para poder exibir dados específicos de Clientes do tipo de pessoa física e pessoa jurídica. Veja figura abaixo:

Agora vamos implementar o código no botão Gravar.

  Try
            Dim clsCliente As Classes.clsCliente

            If optFisica.Checked = True AndAlso optJuridica.Checked = False Then
                "Se for pessoa Fisica
                Dim clsFisica As New Classes.clsPessoaFisica
                clsFisica.pefCPF = txtCPF.Text
                clsFisica.pefRG = txtRG.Text
                clsCliente = clsFisica
            ElseIf optJuridica.Checked = True AndAlso optFisica.Checked = False Then
                "Se for pessoa Jurídica
                Dim clsJuridica As New Classes.clsPessoaJuridica
                clsJuridica.pejCNPJ = txtCNPJ.Text
                clsJuridica.pejInscricaoEstadual = txtInscricaoEstadual.Text
                clsJuridica.pejNomeFantasia = txtNomeFantasia.Text
                clsCliente = clsJuridica
            End If

            clsCliente.cliNome = txtNome.Text
            clsCliente.cliTelefone = txtTelefone.Text
            clsCliente.Gravar()
      Catch OleDbex As OleDb.OleDbException
            MessageBox.Show(OleDbex.Message.ToString())
      Catch ex As Exception
            MessageBox.Show(ex.Message.ToString())
      Finally
            MessageBox.Show("Cliente gravado com sucesso!")
  End Try

Se você reparar na figura do formulário de cadastro, poderá perceber que criei um botão chamado Pesquisar. Este botão irá chamar outro formulário que trará os clientes de acordo com a seleção de um RadioButton. Veja figura abaixo:

Agora vamos adicionar o código que irá retornar um DataSet e irá preencher os dados do DataGrid.

   Dim clsCliente As Classes.clsCliente

   If optFisica.Checked = True AndAlso optJuridica.Checked = False Then
        Dim clsFisica As New Classes.clsPessoaFisica
        clsCliente = clsFisica
   ElseIf optJuridica.Checked = True AndAlso optFisica.Checked = False Then
        Dim clsJuridica As New Classes.clsPessoaJuridica
        clsCliente = clsJuridica
   Else
        MessageBox.Show("Selecione um tipo de cliente!")
   End If

   dgdGrid.DataSource = clsCliente.Retornar()

Pronto, agora basta testar se sua aplicação está gravando no banco de dados e exibindo os dados no DataGrid.

Observações:

Preste muita atenção no código de gravação e pesquisa de clientes. Veja que declarei uma variável clsCliente do tipo da classe de cliente. Depois fiz a verificação de qual tipo de cliente o meu usuário está trabalhando (Física ou Jurídica). Após isso eu atribui minha variável de tipo de cliente, física ou jurídica, na variável clsCliente e chamei o método gravar() e pesquisar(). Fazendo isso o sistema irá saber com qual cliente eu estou trabalhando e irá chamar o método devido. Se eu precisar adicionar um novo tipo de cliente eu apenas vou fazer a validação no IF e setar minha variável clsCliente com o novo tipo de cliente e esta irá chamar o método Override da minha nova classe.

Quando utilizar Overloads?

Se você não colocar a palavra-chave Overloads, seus métodos vão funcionar com sobrecarga normalmente. Mas para deixar de forma explícita e de fácil entendimento para outro desenvolvedor utilize Overloads sempre que você criar funções ou procedimentos com o mesmo nome. A única restrição do Overloads é criar funções ou procedimentos com parâmetros com o mesmo tipo de dados, ou seja, com a mesma assinatura. Por exemplo:

Por que, na classe clsCliente, você utilizou a palavra-chave Overridable sendo que o método não está implantado?

Fiz isso somente para mostrar como fazer. Como o meu método não está implementado o correto seria utilizar a palavra-chave MustOverride. Sendo assim eu criaria apenas a assinatura do método e nas classes derivadas eu faria a implementação do método. Ficaria assim:

No início é um pouco complicado saber quando usar o que, mas com o tempo, estudo e dedicação você irá saber qual palavra-chave e tipos de implementação utilizar sem muitos problemas.

Minha dica é: faça, sempre que possível, uma revisão de seu código. Se você encontrar Functions de validação, acesso a banco e cálculos mirabolantes é porque algo está errado. Utilize SEMPRE as classes.

Caso esqueça de alguma implementação ou palavra-chave, utilize o artigo POO – Programação Orientada a Objetos Parte 1 como guia de referência.

Estou disponibilizando o projeto, banco de dados (Access 2000) e o diagrama de classes feito no Visio Enterprise Architects.

Para baixar o projeto completo, clique aqui.

Até a próxima!

David Pomarico

David Pomarico

David Pomarico - Analista de Sistemas, MCP (Micrososft Certified Professional) em ASP.NET e WindowsForms, atualmente trabalhando em uma multinacional, graduado em Tecnologia em Desenvolvimento de Softwares na Faculdade Informática e Administração Paulista (FIAP), Co-Líder do Grupo de Usuários Codificando.Net SP (www.codificando.net), experiência de 2 anos em .NET, conhecimentos e práticas em Framework .NET, ASP.NET, WinForms, Pocket PC, VB.NET, C#, Crystal Reports.NET, Active Reports for .NET, MS SQL 2000, Oracle 9i, UML, XML.
Visite o meu The spoke: http://br.thespoke.net/MyBlog/dpomarico/MyBlog.aspx