VB .NET - Programação Orientada a Objetos (em 10 lições práticas) - III


VB .NET é uma linguagem orientada a objetos.

Na primeira parte deste artigo apresentei os conceitos chaves da orientação a objetos na linguagem VB .NET, e agora vamos mostrar como criar uma aplicação VB .NET aplicando os conceitos abordados.

Lição 10 - Juntando todas as partes - I

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 é conhecer bem os conceitos e praticar. Então vamos lá...

Os exemplos mostrados aqui foram construídos com base nos exemplos do livro : OOP with Microsoft Visual Basic .NET and Microsoft Visual C# Step by Step.

- Criando sua primeira aplicação orientada a objetos com VB .NET

Nesta primeira aplicação você vai aprender a :

Objetivo: Criar uma aplicação Windows Forms que exiba textos em tamanhos de páginas específicos.

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ê possui baixado no seu computador diversos livros e deseja selecionar um livro e ler uma página particular podendo definir o tamanho desta página.

Interface: A interface da aplicação foi criada no Visual Studio 2012 Express for desktop e utiliza os controles ListBox, RichTextBox, Labels, NumericUpDown.

Construindo a interface

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 LeitorVBNET 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:

Criar a interface usando o Visual Studio 2012 Express for desktop é bem simples, mas agora nossa preocupação é saber :

Para responder essas perguntas vamos usar os conceitos da programação orientada a objetos.

Definindo as classes

Antes que você possa implementar suas classes, você deve decidir quais as classes que você precisa. Primeiro você deve olhar para os objetos do problema.

Tendo encontrado os objetos, então você olha para as propriedades, que são características ou qualidades que pertencem ao objeto e os métodos, que são os comportamentos do objeto.

Você pode escolher entre muitas maneiras de projetar as classes em um aplicativo. A abordagem aqui apresentado começa com uma análise textual do problema.

Os substantivos são selecionados como candidatos às classes, enquanto os verbos se tornam candidatos aos métodos.

No curso da análise, você vai eliminar muitos dos substantivos como candidatos, e você pode descobrir classes que não estão entre os substantivos na especificação.

Depois de determinar os objetos, propriedades e métodos que pertencem a suas classes, você pode escrever a especificação da classe que você vai usar na implementação.

Encontrando as classes

1- lendo o texto do problema e identificando todos os substantivos:

Você possui baixado no seu computador o texto de diversos livros e deseja selecionar um livro e ler uma página particular por vez podendo definir o tamanho desta página.

Podemos eliminar computador, texto, tamanho e página pois são irrelevantes para o problema não podendo gerar comportamento para qualificar uma classe.

Ficamos então com livro e o seu plural livros que podem representar classes potenciais para expressar o domínio do nosso problema.

Nosso problema deverá tratar com livro, onde um livro contém um título e um texto que pode ser lido, e livros, onde livros representa uma coleção de livros e que por isso vamos chamar de Livraria.

Definimos portanto duas classes no problema: Livro e Livraria.

Encontrando propriedades e métodos

2- lendo o texto do problema e identificando todos os verbos:

Você possui baixado no seu computador o texto de diversos livros e deseja selecionar um livro e ler uma página particular por vez podendo definir o tamanho desta página.

Considerando cada verbo devemos verificar se ele é um método ou pode indicar um método e se é relevante para o problema. Assim temos:

Propriedades da classe Livro:

Vamos então verificar se estamos no caminho certo.

Podemos armazenar e organizar diversos livros ? Sim, podemos criar um Livro e armazenar cada livro formando um Livraria usando o método AdicionarLivro.

Podemos selecionar um livro e ler uma página do livro por vez ? Sim, podemos selecionar um livro pelo título usando o método SelecionarLivro e usar o método getPagina para retornar uma página.

Podemos definir o tamanho da página ? Sim, podemos usar a propriedade TamanhoPagina para definir o tamanho da página.

Percebemos que estamos indo na direção certa. Vamos relacionar os métodos e propriedades das nossas classes:

Classe Propriedades Métodos
Livro TamanhoPagina - Integer
  • GetPagina( numeroPagina as integer) as String
  Texto - String  
  Titulo - String  
Livraria  
  • SelecionarLivro(titulo as string) as Livro
  • AdicionarLivro(aLivro as Livro)

Criando a classe Livro

No menu PROJECT clique em Add Class;

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

A seguir vamos definir na classe Livro o seguinte código:

Public Class Livro

  
 '1 - construtor
    Sub New()
    End Sub

   
'2 - campos
    Public Texto As String = ""
    Public TamanhoPagina As Integer = 10

    '3 - propriedade
    Public Property Titulo As String

    '4 - método
    Public Function GetPagina(ByVal numeroPagina As Integer) As String
      
 Dim inicio As Integer = (numeroPagina - 1) * TamanhoPagina
        If (inicio < Texto.Length) And (inicio >= 0) Then
            If (inicio + TamanhoPagina) < Texto.Length Then
                Return Texto.Substring(inicio, TamanhoPagina)
            Else
                Return Texto.Substring(inicio, Texto.Length - inicio)
            End If
        Else
            Return ""
        End If

    End Function

End Class

Vamos entender o código:

O modificador Public na classe Livro : Public Class Livro , indica que a classe poderá ser usada e acessada em todo o projeto.

A classe Livro possui um construtor padrão vazio definido como :

Sub New()
End Sub

Geralmente o construtor contém código para inicializar os campos das classes e realizar outras operações de inicialização. Ele será executado toda a vez que a classe for instanciada com o operador new.

Não é obrigatório definir um construtor, em nosso exemplo eu apenas declarei o construtor para mostrar como é a sintaxe da declaração no VB .NET.

Definimos os campos (fields) Texto e TamanhoPagina como sendo do tipo String e Integer e atribuindo valores iniciais aos mesmos:

Public Texto As String = ""
Public TamanhoPagina As Integer = 10

Um campo é uma variável declarada na classe e pode ser de qualquer tipo de dados da plataforma .NET

Se não tivéssemos atribuído valores iniciais aos campos os valores default seriam atribuídos pelo compilador. Para campos do tipo String um valor "" seria atribuído e para campos Integer seria atribuído o valor zero.

Os campos utilizam o modificar Public significando que podem ser acessados sem restrição.

O acesso direto aos dados de uma classe é uma violação de um princípio básico da orientação a objeto : o encapsulamento da informação.

Por isso definimos propriedades para acessar os campos sendo que os campos são declarados com Private e as propriedades como Public.

A propriedade Titulo foi definida usando a nova sintaxe das propriedades auto implementadas : Public Property Titulo As String

A sintaxe antiga usada pelo VB .NET usava as declarações get/set nas propriedades. 
Onde get obtinha o valor e set atribuia valores. 
Abaixo vemos como ficaria a propriedade Titulo na sintaxe antiga:
private m_titulo as String
Public Property Titulo() As String
   Get
      Return m_titulo
   End Get
      Set(ByVal value As String)
      m_titulo = value
   End Set
End Property

Uma propriedade permite obter e atribuir valores a um campo privado da classe.

A diferença entre propriedade e campo é que para os campos é reservado um valor na memória pois eles contém dados. As propriedades somente permitem o acesso aos campos e não possuem dados.

As propriedades podem ser Public, Private, somente-leitura (ready-only), somente-escrita (write-only).

As propriedades podem ser usadas para validar dados da classe e esconder sua implementação.

Podemos visualizar a estrutura da classe usando a opção Class View no menu VIEW:

Criando a classe Livraria

No menu PROJECT clique em Add Class;

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

A seguir defina o código abaixo na classe Livraria:

Public Class Livraria

    Private prateleira As New SortedList()

    ''' <summary>
    ''' AdicionarLivro
    ''' </summary>
    ''' <param name="novoLivro"></param>
    ''' <remarks></remarks>

    Public Sub AdicionarLivro(ByVal novoLivro As Livro)
        prateleira.Add(novoLivro.Titulo, novoLivro)
    End Sub

    ''' <summary>
    ''' SelecionarLivro
    ''' </summary>
    ''' <param name="titulo"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Function SelecionarLivro(ByVal titulo As String) As Livro
        Dim _livro As Livro
        _livro = CType(prateleira(titulo), Livro)
        prateleira.Remove(titulo)
        Return _livro
    End Function

End Class

Entendendo o código:

Definimos a variável prateleira como uma instância da classe SortedList : Private prateleira As New SortedList()

A classe SortedList é uma classe do .NET Framework existente no namespace System.Collections e representa uma coleção de pares chave/valor que são ordenados pelas chaves e são acessíveis por chave e por índice.

Um elemento SortedList pode ser acessado por sua chave, como um elemento em qualquer implementação de IDictionary, ou por seu índice, como qualquer elemento em uma implementação de IList.

Operações em um SortedList objeto tendem a ser mais lenta do que as operações em um Hashtable o objeto por causa da classificação. No entanto, o SortedList oferece mais flexibilidade, permitindo o acesso aos valores por meio das chaves associadas ou os índices.

Vamos usar a instância da classe SortedList para armazenar e selecionar livros (dai seu nome prateleira), sendo que os livros adicionados serão ordenados automaticamente.

Como definimos a variável prateleira como Private seu acesso será restrito ao escopo da classe.

No método AdicionarLivro(byval novoLivro as Livro) usamos o método Add do objeto prateleira para incluir um novo livro na coleção. Note que precisamos informar o titulo do livro (chave) e um objeto do tipo Livro (valor).

No método SelecionarLivro(byval titulo as String) definimos um objeto _livro do tipo Livro e estamos localizando o livro pelo titulo na prateleira realizando uma conversão forçada (casting) para o tipo Livro: CType(prateleira(titulo), Livro)

Após selecionar o livro usamos o método Remove do objeto prateleira para remover o livro da mesma e retornamos o livro: Return _livro

Dessa forma nossa classe Livraria esta pronta para ser usada.

Definindo o código do formulário

Agora podemos retornar ao formulário da aplicação e utilizar os eventos dos controles do formulário para definir as ações que desejamos controlar em nossa aplicação usando as classes definidas e interagindo com o usuário.

É através do formulário, seus controles e eventos que o usuário poderá interagir com a aplicação e usar os recursos implementados em nossas classes.

Se você visualizar o código de um formulário vai perceber que ele é uma classe. No nosso exemplo note a declaração Public Class Form1 explicitando a definição do formulário Form1:

Public Class Form1
End Class

Dessa forma os formulários que usamos em qualquer projeto VB .NET são classes e possui diversos métodos e eventos, alguns dos quais iremos usar em nossa aplicação.

Vamos iniciar definindo uma variável do tipo Livraria no início da classe Form1:

Private _livraria As Livraria

Isso é necessário para que ela seja visível em todo o formulário. Como definimos a variável como Private ela somente será visível neste formulário.

Agora vamos usar o evento Load do formulário que ocorre quando ele é carregado pela primeira vez definindo o seguinte código neste evento:

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

Dessa forma toda a vez que esse formulário for aberto o evento Load será chamado e a rotina CarregaDados() será executada.

Na rotina CarregaDados() vamos criar uma instância da Livraria e criar dois objetos da classe Livro adicionando-os na Livraria.

Para isso digite o código abaixo na rotina CarregaDados:

    Private Sub CarregaDados()
        _livraria = New Livraria()

        Dim _receitas As New Livro()
        _receitas.Texto = "Bolo de chocolate com cobertura de morango é uma delício."
        _receitas.TamanhoPagina = 8
        _receitas.Titulo = "Receitas"

        Dim _contos As New Livro()
        _contos.Texto = "Era uma vez nos tempos dos cavalheiros e das cruzadas."
        _contos.TamanhoPagina = 8
        _contos.Titulo = "Rei Artur"

        _livraria.AdicionarLivro(_receitas)
        _livraria.AdicionarLivro(_contos)

        lbLivros.Items.Add(_receitas.Titulo)
        lbLivros.Items.Add(_contos.Titulo)

    End Sub

Criamos uma instância da classe Livraria : _livraria para podemos adicionar os livros.

A seguir criamos duas instâncias da classe Livro : _receitas e _contos e atribui valores às suas propriedades Texto, TamanhoPagina e Titulo.

Usando o método AdicionarLivro() incluímos os livros na livraria

E para exibir os valores do dos títulos dos livros no controle ListBox (lbLivros) usamos o método Add do controle.

Esta faltando exibir a página do livro no controle RichTextBox.

Para isso o usuário deverá selecionar um livro exibido no controle ListBox e sua página será exibida no controle RichTextBox.

Vamos usar o evento SelectedIndexChanged do controle ListBox.

Esse evento ocorre quando houver qualquer mudança na propriedade SelectedIndex do controle. Quando um usuário seleciona um item no ListBox essa propriedade muda de valor e o evento é disparado.

Para abrir o código do evento no formulário basta clicar duas vezes sobre o controle ou na janela de propriedades clicar no ícone para exibir as propriedades e clicar duas vezes sobre a propriedade SelectedIndexChanged:

Inclua o código abaixo neste evento:

    Private Sub lbLivros_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lbLivros.SelectedIndexChanged

        Dim _titulo As String = lbLivros.SelectedItem.ToString()
        Dim _livro As Livro = _livraria.SelecionarLivro(_titulo)

        _livro.TamanhoPagina = nupd_TamanhoPagina.Value

        lblTituloLivro.Text = _livro.Titulo

        rchtPagina.Text = _livro.GetPagina(nupd_PaginaExibir.Value)

        _livraria.AdicionarLivro(_livro)

    End Sub

Entendendo o código:

Obtemos o título do livro selecionando no controle ListBox usando o método SelectedItem do controle e usamos o método ToString() para converter o valor para String : Dim _titulo As String = lbLivros.SelectedItem.ToString()

e atribuímos o valor a variável _titulo do tipo String. (String é um tipo de dados onde armazenamos valores alfanuméricos)

Procuramos o livro na livraria usando o método SelecionarLivro e passando o titulo do livro: Dim _livro As Livro = _livraria.SelecionarLivro(_titulo)

O valor retornado é um livro que será armazenado no objeto _livro.

A seguir atribuímos o valor definido no controle NumericUpDown nupd_TamanhoPagina : _livro.TamanhoPagina = nupd_TamanhoPagina.Value

Obtendo o tamanho da página.

Atribuímos o valor do título do livro à Label lblTituloLivro;

Obtemos a página usando o método GetPagina() e passando o valor definido no controle nupd_PaginaExibir para página a exibir:

Adicionamos o livro na livraria: _livraria.AdicionarLivro(_livro)

Abaixo vemos o código completo do formulário Form1:

Public Class Form1

    Private _livraria As Livraria

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CarregaDados()
    End Sub
    Private Sub CarregaDados()
        _livraria = New Livraria()

        Dim _receitas As New Livro()
        _receitas.Texto = "Bolo de chocolate com cobertura de morango é uma delício."
        _receitas.TamanhoPagina = 8
        _receitas.Titulo = "Receitas"

        Dim _contos As New Livro()
        _contos.Texto = "Era uma vez nos tempos dos cavalheiros e das cruzadas."
        _contos.TamanhoPagina = 8
        _contos.Titulo = "Rei Artur"

        _livraria.AdicionarLivro(_receitas)
        _livraria.AdicionarLivro(_contos)

        lbLivros.Items.Add(_receitas.Titulo)
        lbLivros.Items.Add(_contos.Titulo)

    End Sub

    Private Sub lbLivros_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lbLivros.SelectedIndexChanged

        Dim _titulo As String = lbLivros.SelectedItem.ToString()
        Dim _livro As Livro = _livraria.SelecionarLivro(_titulo)

        _livro.TamanhoPagina = nupd_TamanhoPagina.Value

        lblTituloLivro.Text = _livro.Titulo

        rchtPagina.Text = _livro.GetPagina(nupd_PaginaExibir.Value)

        _livraria.AdicionarLivro(_livro)

    End Sub
End Class

Executando o projeto e selecionando um titulo vemos o resultado a seguir:

Pegue o projeto completo aqui: LeitorVBNET.zip

Na próxima aula irei mostrar como podemos como podemos usar herança e criar classes especializadas.

Referências:


José Carlos Macoratti