VB.NET - Juntando as partes - Criando uma aplicação OOP  

Este artigo encerra a seqüência que aborda os conceitos básicos sobre a implementação OOP no VB .NET. Abaixo os links de cada artigo para você acompanhar:

  1.  VB.NET - Primeiros passos - Conceitos - I

  2.  VB.NET - Primeiros passos - Conceitos - II

  3.  VB.NET - Primeiros passos - Conceitos - III

  4.  VB.NET - Primeiros passos - Conceitos - IV

  5.  VB.NET - Primeiros passos - Conceitos - V

  6.  VB.NET - Primeiros passos - Conceitos - VI

Neste artigo vou procurar mostrar uma aplicação prática dos conceitos OOP de forma que você possa ter uma visão geral e de como por em prática toda esta teoria.

A mentalidade da programação orientada a objetos está em modelar os objetos definindo suas propriedades, determinando os dados necessários e eventos e métodos que o objeto vai utilizar. No VB .NET, controles tais como o TextBox ou ListBox são por definição classes.

Assim um TextBox chamado txtNome quando incluído em um formulário inicializa o código Friend WithEvents txtNome As System.Windows.Forms sendo que o TextBox será incluído na seção Windows Form Designer generate Code para criar uma instância da classe TextBox.

Após a classe ser instanciada o objeto pode ser usado no seu projeto a vontade. Vamos então ao trabalho...

Embora VB .NET seja realmente uma linguagem orientada a objetos você pode usar a linguagem da mesma forma que usa uma linguagem estruturada como Visual Basic ou Pascal. Se você não incorporar os conceitos da orientação a objetos e aplicá-los em seus projetos construirá aplicações usando os mesmos conceitos das linguagens estruturadas. Isso não é de todo ruim mas você acaba não usando os recursos da linguagem e continua a construir projetos usando o paradigma procedural.

É como se você tivesse uma Ferrari mas se comportasse como se tivesse um fusca.

O segredo para incorporar os conceitos da orientação a objetos em suas aplicações e conhecer bem os conceitos e praticar. Então vamos lá...

- Usando herança para criar classes especializadas

Nesta aplicação você vai aprender a :

Objetivo: Criar uma pequena aplicação para controlar os saques , depósitos e saldos de uma conta pessoal usando os conceitos programação orientada a objetos na linguagem VB .NET.

Recursos usados : Visual Studio 2012 Express for Windows desktop

Nota: Neste momento já se encontra disponível a versão 2013 : http://www.microsoft.com/visualstudio/eng/2013-downloads

É importante salientar que a ferramenta usada é gratuita, não possui restrições sendo totalmente funcional. Ao fazer o download da ferramenta você também pode baixar o pacote de idioma para localizar o produto para a língua portuguesa.

Problema: Você deseja controlar sua conta bancária pessoal registrando os saques, depósitos e controlando o saldo da conta.

Conceitos Básicos - Herança

A herança é o método de programação usada para implementar a relação é-um (is-a) de um projeto orientado a objetos.

Dessa forma temos que um Botão é-um controle, um Cão é-um mamífero, uma conta de Poupança é-uma conta bancária, etc.

Nota: Você não deve confundir herança com composição que modela um relacionamento tem-um (has-a) entre um objeto e suas propriedades. Assim um Botão tem-um título, um Cão tem-um nome, uma conta de Poupança tem-um saldo, etc.

A herança permite criar classes a partir de classes existentes. Podemos criar novas classes a partir de uma classe base.

Neste caso podemos dizer que a classe derivada herda ou deriva da classe base. Outra terminologia comum usa superclasse para a classe base e subclasse para a classe derivada.

Definindo a classe base

Para a nossa aplicação de controle bancário pessoal vamos criar uma classe base chamada Conta.

Quando você pensa em uma conta bancária o que lhe vem a mente ?

O dono da conta(titular) , o saldo da conta, o número da conta (ID), os valores a débito(saques) e a crédito(depósitos), etc.

Dessa forma podemos identificar os seguintes membros:

Membro Descrição
Titular Uma propriedade string que identifica o titular da conta
ID Uma propriedade string somente-leitura que identifica a conta
Saldo Uma propriedade decimal somente-leitura. O valor dessa propriedade depende dos depósitos e saques feitos na conta.
Deposito Método que usa um parâmetro : o valor depositado. Ele retorna o saldo após o deposito.
Saque Método que usa um parâmetro : o valor do saque. Ele retorna o saldo após o saque.

Construindo o projeto

Abra o Visual Studio 2012 Express for desktop e clique em New Project;

Selecione o template : Visual Basic -> Windows -> Windows Forms Application;

Informe o nome ControleBancario e clique no botão OK:

A seguir vamos incluir os seguintes controles no formulário form1.vb :

O leiaute do formulário é visto abaixo:

Criando a classe base, as propriedades , métodos e o construtor da classe base

No menu PROJECT clique em Add Class;

Selecione o template Class e informe o nome Conta.vb e clique em Add;

1 - Definindo as propriedades e o construtor da classe base

Vamos iniciar definindo as propriedades ID e Saldo da conta e o construtor da classe. Essas propriedades são somente-leitura indicando que ela não podem ser alteradas somente lidas.

Abaixo temos o código definido na classe Conta :

Public Class Conta

    Private _titular As String
    Public ReadOnly Property ID() As String
        Get
            Return _titular
        End Get
    End Property

    Private _saldo As Decimal
    Public ReadOnly Property Saldo() As Decimal
        Get
            Return _saldo
        End Get
    End Property

    Public Sub New(ByVal titular As String)
        _titular = titular
        _saldo = 0D
    End Sub

End Class
Eu estou usando a sintaxe anterior a versão 4.0 para que o código seja compatível com as versões anteriores.

Para ver a nova sintaxe veja o meu artigo sobre propriedades autoimplementadas:
VS2010 - VB .NET - Novos Recursos - Macoratti.net

2 - Definindo os métodos da classe base

Agora vamos definir os métodos Deposito e Saque da classe base usando a seguinte lógica:

Inclua na classe Conta o código para os métodos conforme abaixo:

    Public Function Deposito(ByVal valor As Decimal) As Decimal
        _saldo += valor
        Return _saldo
    End Function

    Public Function Saque(ByVal valor As Decimal) As Decimal
        _saldo -= valor
        Return _saldo
    End Function

Usando a classe Conta no projeto Windows Forms

Vamos agora testar a nossa classe Conta realizando saldos e depósitos e obtendo o saldo em nosso projeto Windows Forms.

A primeira coisa que temos que fazer e criar uma instância da classe Conta no início do formulário form1.vb:

Dim contaMacoratti As New Conta("Macoratti")

O código acima defina o objeto ContaMacoratti usando o construtor da classe Conta com o parâmetro "Macoratti" que é o nome do titular e passa a ser o ID da conta.

Após isso podemos exibir o saldo da conta ContaMacoratti. Então no evento Load do formulário vamos chamar a rotina atualizaSaldo() que exibe o saldo atualizado:

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        atualizaSaldo()
    End Sub

O código da rotina atualizaSaldo() é dado a seguir:

 Private Sub atualizaSaldo()
        lblSaldo.Text = contaMacoratti.Saldo
    End Sub

O código exibe o valor do saldo na label lblSaldo.Text. Como quando iniciarmos o projeto o construtor inicia o valor do saldo com zero o valor exibido será sempre zero no início do programa.

A seguir podemos definir o código do botão Depositar que irá realizar depósitos na conta no evento Click do botão de comando:

Private Sub btnDepositar_Click(sender As Object, e As EventArgs) Handles btnDepositar.Click
        Dim valor As Decimal = 0D

        If String.IsNullOrEmpty(txtValorDeposito.Text) Then
            MessageBox.Show("Informe um valor para depósito!")
        Else
            valor = Convert.ToDecimal(txtValorDeposito.Text)
            contaMacoratti.Deposito(valor)
            atualizaSaldo()
        End If
    End Sub

Definimos a variável valor como Decimal e inicializamos o seu valor com zero (0D): Dim valor As Decimal = 0D

Verificamos se o valor informado no TextBox txtValorDeposito.Text pelo usuário é nulo ou vazio e avisamos o usuário: String.IsNullOrEmpty(txtValorDeposito.Text)

Quando o usuário informar um valor no TextBox iremos converter o valor informado para Decimal usando o método ToDecimal da classe Convert : valor = Convert.ToDecimal(txtValorDeposito.Text)

Chamamos o método Deposito da classe com o valor informado: contaMacoratti.Deposito(valor)

E chamamos a rotina para exibir o saldo atualizado : atualizaSaldo()

De forma a permitir somente valores válidos no TextBox txtValorDeposito.Text vamos usar o evento KeyPress e permitir somente valores numéricos , o ponto e a vírgula:

 Private Sub txtValorDeposito_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtValorDeposito.KeyPress
        If Not Char.IsNumber(e.KeyChar) And Not e.KeyChar = vbBack And Not e.KeyChar = "." And Not e.KeyChar = "," Then
            e.Handled = True
        End If
    End Sub

Neste momento já podemos executar a aplicação e realizar depósitos :

Fig 1.0 - Janela inicial do projeto Fig 2.0 - Feito um depósito de 100

Na janela inicial teremos o saldo da conta exibido como valor zero e podemos digitar um valor e realizar um depósito.

Informando o valor 100 e clicando no botão Depositar teremos o saldo atualizado para 100.

Vamos agora definir o código do botão Sacar que deverá usar o método Saque da classe Conta e decrementar o saldo do valor informado. Abaixo vemos o código do evento Click do botão Sacar:

 Private Sub btnSacar_Click(sender As Object, e As EventArgs) Handles btnSacar.Click
        Dim valor As Decimal = 0D

        If String.IsNullOrEmpty(txtValorSaque.Text) Then
            MessageBox.Show("Informe um valor para Saque!")
        Else
            valor = Convert.ToDecimal(txtValorSaque.Text)
            contaMacoratti.Saque(valor)
            atualizaSaldo()
        End If
    End Sub

O código é idêntico ao do botão depositar. A única exceção é que chamamos o método Saque da classe conta com o valor informado: contaMacoratti.Saque(valor)

De forma a permitir somente valores válidos no TextBox txtValorSaque.Text vamos usar o evento KeyPress e permitir somente valores numéricos, o ponto e a vírgula:

 Private Sub txtValorSaque_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtValorSaque.KeyPress
        If Not Char.IsNumber(e.KeyChar) And Not e.KeyChar = vbBack And Not e.KeyChar = "." And Not e.KeyChar = "," Then
            e.Handled = True
        End If
    End Sub

Após realizarmos dois depósitos no valor de R$ 100 e um saque no valor de R$ 50 teremos o resultado abaixo:

Se espiarmos a classe conta no Class View (Menu VIEW-> Class View) iremos obter:

Criando uma classe derivada da classe base

Vamos agora criar um nova classe chamada Poupanca que deverá ser uma classe derivada da nossa classe base Conta.

Quando você estende uma classe para criar uma nova classe , a nova classe estendida herda todas as propriedades e métodos da classe que foi estendida. A classe original é conhecida como superclasse , classe pai ou classe base ; a classe que estendida é conhecida como classe filha ou subclasse.(Se a classe filha não sobrepõe(overrides) nenhum procedimento da classe pai ,  ela herda todo o comportamento da classe pai.)

Algumas das características importantes sobre herança no VB.NET são:

A classe Poupanca é idêntica a classe Conta exceto em relação aos seguintes aspectos:

Vamos criar a classe Poupança herdando da classe Conta para isso vamos usar a palavra-chave Inherits. No menu PROJECT clique em Add Class, selecione o template Class e informe o nome Poupanca.vb.

A seguir digite o código abaixo nesta classe:

Note que o compilador emite uma mensagem de erro:

Error 1 Class 'ControleBancario.Poupanca' must declare a 'Sub New' because its base class 'ControleBancario.Conta'
does not have an accessible 'Sub New' that can be called with no arguments.

numa tradução livre: A classe 'ControleBancario.Poupanca' deve declarar um 'Sub New' pois classe base 'ControleBancario.Conta' não tem um Sub New acessível que pode ser chamado sem argumentos.

O erro indica que temos que declarar um construtor para a classe Poupanca pois o construtor da classe Conta não esta acessível.

Os construtores não são herdados, portanto, você deve adicioná-los na classe derivada. Além disso, sempre que um construtor é definido, ele inclui uma chamada implícita para o construtor sem parâmetros que pertence à classe base.

Na classe Conta, criamos somente um único construtor público que possui um parâmetro para o nome do titular da conta. Como o construtor sem parâmetros não existe na classe base, temos que fazer uma chamada explicita ao construtor. Logo temos que incluir esse construtor na classe Poupanca.

Vamos corrigir o erro digitando o código abaixo:

Este código introduz a palavra-chave MyBase.

MyBase refere-se à classe base da classe derivada. No caso do construtor, não há sentido em reescrever o código que você escreveu na classe base Conta. Uma chamada para a classe base é suficiente: MyBase.New()

Vamos agora pensar um pouco sobre as propriedades da classe Poupanca; iniciando pela propriedade ID que deverá identificar a conta de poupança.

Vamos identificar uma conta de poupança usando o nome do titular acrescentando o sufixo -P ao nome do titular da conta. Assim o titular da conta com o nome Macoratti será identificado na conta de poupança como Macoratti-P.

Para implementar isso na classe Poupanca teremos que modificar a propriedade ID que esta sendo herdada da classe Conta pela classe Poupanca sobrescrevendo o seu comportamento.

Para poder sobrescrever o seu comportamento usamos o modificador overrides na classe derivada conforme mostramos a seguir:

Observe que o compilador reporta um erro indicando que para podermos sobrescrever a propriedade ID na classe derivada temos que declará-la como Overridable na classe base. Então retorne a classe base Conta e altere o modificar da propriedade ID:

 Public Overridable ReadOnly Property ID() As String
        Get
            Return _titular
        End Get
    End Property

Agora podemos retornar à classe Poupanca e terminar a implementação da propriedade ID:

Agora temos outro erro. O compilador indica que o membro _titular da classe base não esta acessível.

Lembre que o membro _titular foi definido como Private e por isso esta visível somente na classe de origem. Para resolver esse erro temos que alterar o modificador do membro _titular de Private para Protected na classe Conta:

Protected _titular As String
    Public Overridable ReadOnly Property ID() As String
        Get
            Return _titular
        End Get
    End Property

Com isso o erro será revolvido visto que modificador Protected torna a variável de uma classe base somente acessível as suas classes derivadas. O código final na classe Poupanca da propriedade ID ficou assim:

 Public Overrides ReadOnly Property ID() As String
        Get
            Return Me._titular + "-P"
        End Get
    End Property

Este código apresenta a palavras-chave Me que refere-se a instância de classe. Neste caso, utilizar Me não é obrigatório, poderíamos digitar apenas _titular.

Você pode usar a palavra-chave Me em situações em que você pode ter conflitos com nomes de variáveis.Talvez você tenha o mesmo campo declarado na classe e no método, neste caso a palavra-chave Me indica qual variável você deve usar.

Vamos agora definir a propriedade Juros na classe derivada Poupanca conforme o código abaixo:

Private _juros As Decimal = 0.01
    Public Property Juros() As Decimal
        Get
            Return _juros
        End Get
        Set(ByVal Value As Decimal)
            _juros = Value
        End Set
 End Property

Esta propriedade foi definida com um valor inicial :Private _juros As Decimal = 0.01

Agora crie o método AdicionarJuros na classe Poupanca conforme o código a seguir:

Public Function AdiconarJuros() As Decimal
        Me.Deposito(_juros * Me.Saldo)
        Return Me.Saldo
End Function

O código acima usa o método Deposito da classe base para incluir o valor do saldo atual acrescidos dos juros usando a propriedade Saldo.

Como campo _saldo foi definido como Private na classe base Conta e a propriedade Saldo é somente-leitura.Portanto, a única maneira de adicionar dinheiro na conta é, por definição, através do método Deposito.

Testando a classe Poupança no projeto Windows Forms

Para podermos testar a nova classe Poupanca que foi derivada da classe base Conta em nosso projeto Windows Forms vamos ter que ajustar o formulário para permitir que o usuário escolha depositar e sacar na conta ou na poupança e também permitir que o usuário defina uma taxa de juros e adicione o juros calculado na conta de poupança.

No início do formulário vamos criar uma instância da classe Poupanca:

Dim contaPoupancaMacoratti As New Poupanca("Macoratti")

Dessa forma poderemos usar o objeto contaPoupancaMacoratti com a respectiva conta de poupança criada com nome do titular - Macoratti.

Agora vamos ajustar o formulário. Abra o formulário form1.vb do projeto e inclua os seguintes controles a partir da Toolbox:

Disponha os controles conforme o leiaute da figura abaixo:

Vamos alterar o código dos botões Depositar e Sacar para que as operações sejam feitas na conta escolhida pelo usuário selecionando os controles radiobuttons. O código ajustado ficou assim:

 Private Sub btnDepositar_Click(sender As Object, e As EventArgs) Handles btnDepositar.Click
        Dim valor As Decimal = 0D

        If String.IsNullOrEmpty(txtValorDeposito.Text) Then
            MessageBox.Show("Informe um valor para depósito!")
        Else
            valor = Convert.ToDecimal(txtValorDeposito.Text)
            If rdbDepositoConta.Checked Then
                contaMacoratti.Deposito(valor)
            ElseIf rdbDepositoPoupanca.Checked Then
                contaPoupancaMacoratti.Deposito(valor)
            End If
            atualizaSaldo()
            End If
    End Sub
 
 Private Sub btnSacar_Click(sender As Object, e As EventArgs) Handles btnSacar.Click
        Dim valor As Decimal = 0D

        If String.IsNullOrEmpty(txtValorSaque.Text) Then
            MessageBox.Show("Informe um valor para Saque!")
        Else
            valor = Convert.ToDecimal(txtValorSaque.Text)
            If rdbSaqueConta.Checked Then
                contaMacoratti.Deposito(valor)
            ElseIf rdbSaquePoupanca.Checked Then
                contaPoupancaMacoratti.Deposito(valor)
            End If
            atualizaSaldo()
        End If
    End Sub

Temos que atualizar também a rotina atualizaSaldo de forma a exibir os valores para saldo da conta de poupança.

Private Sub atualizaSaldo()
        lblSaldo.Text = contaMacoratti.Saldo.ToString("C")
        lblSaldoPoupanca.Text = contaPoupancaMacoratti.Saldo.ToString("C")
    End Sub            

No código eu estou usando a instância da classe Poupanca - contaPoupancaMacoratti - e exibindo o saldo através da propriedade Saldo.

Note que estou formatando o resultado usando ToString("C") que formata a saída no formato da moeda local.(R$)

Finalmente vamos definir o código para adicionar os juros ao saldo da poupança usando o evento Click do botão - Adicionar Juros na Conta de Poupança:

  Private Sub btnAdicionarJurosPoupanca_Click(sender As Object, e As EventArgs) Handles btnAdicionarJurosPoupanca.Click
        Dim taxaJuros As Decimal = 0D
        taxaJuros = Convert.ToDecimal(txtJurosPoupanca.Text)
        If taxaJuros <> 0 Then
            'define o valor da taxa de juros na classe de poupança
            contaPoupancaMacoratti.Juros = taxaJuros
        End If
        'inclui os juros na conta de poupança
        contaPoupancaMacoratti.AdicionarJuros()
        atualizaSaldo()
    End Sub

Estamos convertendo o valor informado pelo usuário no TextBox -txtJurosPoupanca.

Se o valor informado for igual a zero estamos atualizando o valor da propriedade Juros. Caso contrário usaremos o valor padrão atribuído na propriedade.

Depois usamos o método AdicionarJuros() do objeto contaPoupancaMacoratti que é uma instância da classe Poupanca.

Executando o projeto e realizando um depósito e adicionando os juros na poupança teremos:

Para concluir esta parte vamos exibir também o nome do titular da conta e da poupança alterando a rotina atualizaSaldo:

Private Sub atualizaSaldo()
        lblTitularConta.Text = contaMacoratti.ID
        lblSaldo.Text = contaMacoratti.Saldo.ToString("C")
        lblTitularPoupanca.Text = contaPoupancaMacoratti.ID
        lblSaldoPoupanca.Text = contaPoupancaMacoratti.Saldo.ToString("C")
    End Sub

Note que usamos a propriedade ID da classe base(contaMacoratti.ID) e da classe derivada (contaPoupancaMacoratti.ID) , que sobrescreveu o método da classe base:

Executando o projeto novamente e realizando algumas operações temos:

Vimos assim a criação de uma pequena aplicação usando os recursos da orientação a objetos da linguagem VB .NET.

Pegue o projeto completo aqui: ControleBancario.zip


Veja os Destaques e novidades do SUPER DVD VB (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira...

Quer aprender C# ??

Chegou o Super DVD C# com exclusivo material de suporte e vídeo aulas com curso básico sobre C#

Veja também os cursos em Vídeo Aulas :

   Gostou ?   Compartilhe no Facebook    Compartilhe no Twitter

Referências:


José Carlos Macoratti