.NET

26 ago, 2014

Programação Orientada a Objetos em 10 lições práticas – Parte 07

Publicidade

Até o momento, apresentamos os conceitos da programação orientada a objetos afetos à linguagem VB .NET usando uma aplicação bem simples de controle de saldos bancários, onde definimos uma classe base Conta e uma classe Poupanca que herda dessa classe base (Inherits).

Vimos como criar métodos e propriedades na classe base e como especializar essa classe criando classes derivadas. Vimos, assim, como usar os recursos da herança, sobrescrever um método e como interagir como controles de formulários em uma aplicação Windows Forms. Neste artigo, vamos aplicar o conceito de polimorfismo e mostrar como podemos usar os seus recursos em nossa aplicação bancária.

Polimorfismo – Conceitos e utilização – Parte 07

Nesta aplicação você vai aprender a definir e utilizar polimorfismo.

Objetivo: Criar uma pequena aplicação para controlar os saques, depósitos e saldos de uma conta pessoal usando os conceitos de 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 É importante salientar que a ferramenta usada é gratuita, não possui restrições e é 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 usando os conceitos da programação orientada a objetos da linguagem VB .NET.

Conceitos básicos – Polimorfismo

Polimorfismo significa muitas formas, na orientação a objetos você pode enviar uma mesma mensagem para diferentes objetos e fazê-los responder da maneira correta. Você pode enviar a mensagem “mover” para cada objeto semelhante a um veículo e cada um vai se comportar de maneira diferente para atender a sua solicitação. Quando uma mesma mensagem pode ser processada de diferentes formas, temos um exemplo de polimorfismo.

Uma definição mais formal diria: “Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura), mas comportamentos distintos, especializados para cada classe derivada, usando para tanto, uma referência a um objeto do tipo da superclasse”. Usando polimorfismo podemos:

  1. Invocar métodos da classe derivada através da classe base em tempo de execução;
  2. Permitir que classes forneçam diferentes implementações de métodos que são chamados com o mesmo nome;

Existem dois tipos básicos de polimorfismo:

  1. Polimorfismo em tempo de compilação (Overloading/Sobrecarga);
  2. Polimorfismo em tempo de execução (Overriding/Sobrescrita).

O polimorfismo em tempo de compilação utiliza a sobrecarga de métodos e operadores, sendo também chamado de ligação precoce (early binding). A utilização da sobrecarga de métodos realiza a tarefa com distintos parâmetros de entrada. O polimorfismo, em tempo de execução, pode ser feito usando herança e métodos virtuais (Overridable).

Quando sobrescrevemos (Overrides), os métodos virtuais estamos alterando o comportamento dos métodos para a classe derivada. Isto também é conhecido como ligação tardia (late binding). Nesta aula veremos a utilização de polimorfismo usando herança e métodos virtuais.

Apresentação do cenário

Para tornar o exemplo mais simples e fácil de entender, eu não vou criar um projeto Windows Forms, como fiz na aula anterior. Vou criar um projeto do tipo Console Application. Pegando ‘carona’ no exemplo da classe Conta, vamos aumentar a abstração do exemplo e aplicar os conceitos de polimorfismo.

Imagine uma classe Conta que define os comportamentos e atributos de qualquer Conta. Vamos supor que uma característica básica de qualquer conta seja o comportamento ‘retirar dinheiro’, logo nossa classe Conta pode expressar isso através de um método Sacar().

Outra característica básica de qualquer conta seria o comportamento depositar dinheiro, afinal uma conta deve ter um valor monetário e isso seria expresso na classeConta por um método Depositar(). Vamos definir um atributo para identificar o tipo da conta que será expresso pela propriedade Tipo.

Então, podemos criar uma classe Conta contendo esses métodos e esse atributo e usar o mecanismo da herança para que outras classes herdem os atributos e comportamentos comuns. Tudo bem.

Até aqui não temos nada de novo, foi isso o que fizemos. Vamos então criar uma classe Conta , uma classe ContaPoupanca e uma classe ContaInvestimento, onde as duas últimas irão herdar da classe Conta e veremos como promover o polimorfismo usando o mecanismo da herança com sobrescrita de métodos. Abaixo vemos a representação da herança usando um diagrama UML simplificado: vbn_oop71

Criando o projeto e implementando o polimorfismo com herança e métodos virtuais

Abra o Visual Studio 2012 Express for desktop e clique em New Project. Selecione o template: Visual Basic -> Windows -> Console Application. Informe o nome OOP_Polimorfismo1 e clique no botão OK e no menu PROJECT, clique em Add Class. Selecione o template Class e informe o nome Conta.vb e clique em Add. vbn_oop72 A seguir, vamos definir a propriedade Tipo, um construtor padrão que define o tipo da conta, e os métodos Sacar() e Depositar(), conforme o código a seguir:

Public Class Conta
    Private _tipo As String
    Public Property Tipo() As String
        Get
            Return _tipo
        End Get
        Set(value As String)
            _tipo = value
        End Set
    End Property
    Public Sub New(tipoConta As String)
        Me._tipo = tipoConta
    End Sub
    Public Overridable Sub Sacar()
    End Sub
    Public Overridable Sub Depositar()
    End Sub
End Class

Vamos agora criar a classe ContaPoupanca. No menu PROJECT, clique em Add Class. Selecione o template Class e informe o nome ContaPoupanca.vb e clique em Add. A seguir, inclua o código abaixo para a classe ContaPoupanca, que herda da classe conta. A palavra Inherits indica a herança entre as classes:

Public Class ContaPoupanca
        Inherits Conta
    Public Sub New(tipoConta As String)
        MyBase.New(tipoConta)
    End Sub
    Public Overrides Sub Sacar()
        Console.WriteLine("Sacando da conta de poupança")
    End Sub

    Public Overrides Sub Depositar()
        Console.WriteLine("Depositando na conta de poupanca.")
    End Sub
End Class

Note que o método construtor da classe ContaPoupanca chama o construtor da classe base usando a palavra-chave MyBase.New() e que os métodos Sacar() e Depositar() possuem o modificar Overrides, que indica que esses métodos estão sendo sobrescritos na classe derivada.

Vamos agora criar a classe ContaInvestimento. No menu PROJECT, clique em Add Class. Depois selecione o template Class e informe o nome ContaInvestimento.vb e clique em Add. A seguir, inclua o código abaixo para essa classe que herda da classe conta:

Public Class ContaInvestimento
    Inherits Conta
    Public Sub New(tipoConta As String)
        MyBase.New(tipoConta)
    End Sub
    Public Overrides Sub Sacar()
        Console.WriteLine("Sacando da conta de investimento")
    End Sub
    Public Overrides Sub Depositar()
        Console.WriteLine("Depositando na conta de investimento.")
    End Sub
End Class

Nota: Eu não implementei nenhum código mais complexo nos métodos Sacar() e Depositar() para tornar o exemplo mais simples. Na classe Conta temos:

  1. A propriedade pública Tipo que define o tipo da conta;
  2. O método virtual Sacar() que define o comportamento de retirar dinheiro da conta;
  3. O método virtual Depositar() que define o comportamento de por dinheiro na conta;
  4. O construtor da classe onde definimos o tipo da conta;(Sub New).

O modificador de acesso Overridable indica que o método pode ser sobrescrito na classe derivada. Na classe ContaPoupanca temos:

  1. A classe ContaPoupanca herda da classe Conta; (Inherits);
  2. A classe ContaPoupanca sobrescreve os método Sacar() e Depositar() usando o modificador Overrides;
  3. O construtor da classe ContaPoupanca executa o construtor da classe base; (MyBase.New()).

Na classe ContaInvestimento temos:

  1. A classe ContaInvestimento herda da classe Conta;(Inherits);
  2. A classe ContaInvestimento sobrescreve os método Sacar() e Depositar() usando o modificador Overrides;
  3. O construtor da classe ContaInvestimento executa o construtor da classe base;(MyBase.New()).

Agora vamos definir o código para usar as classes e mostrar o comportamento de polimorfismo. Inclua o código abaixo no Modulo Module1 usando a rotina Main():

Module Module1
    Sub Main()
        Dim conta As Conta() = New Conta(1) {}
        conta(0) = New ContaPoupanca("Poupança do Macoratti")
        conta(1) = New ContaInvestimento("Conta de Investimento do Macoratti")    
        MovimentarConta(conta(0))
        MovimentarConta(conta(1))
        Console.ReadKey()
    End Sub
    Public Sub MovimentarConta(_conta As Conta)
        Console.WriteLine(_conta.Tipo)
        _conta.Sacar()
        _conta.Depositar()
    End Sub
End Module

vbn_oop73 No código cima temos:

  • A criação de um vetor com dois elementos;
  • A criação de duas instâncias, uma de ContaPoupanca e outra de ContaInvestimento;
  • A chamada do método Sacar que simula o comportamento de retirar dinheiro para cada conta;
  • A chamada do método Depositar que simula o comportamento de por dinheiro em cada conta.

Observe que no método MovimentarConta estamos usando o método Sacar() e Depositar() para cada tipo de conta que foi instanciada e cada objeto sabe realizar o comportamento correto em resposta à mesma chamada do método.

Aqui estamos usando o conceito de polimorfismo, pois o método Sacar() e o método Depositar() são executados e a decisão de qual comportamento será usado ocorre em tempo de execução.

Usamos _conta.Sacar() ao invés de ContaPoupanca.Sacar() ou ContaInvestimento.Sacar(). (o mesmo valendo para o método Depositar()) Podemos fazer isso graças a herança que determina que uma ContaPoupanca é uma Conta e que uma ContaInvestimento também é uma Conta.

Para usar o polimorfismo os objetos precisam executar as mesmas ações (métodos) mesmo que possuam comportamentos diferentes.

Pegue o projeto completo aqui:  OOP_Polimorfismo1.zip

Na próxima aula irei continuar a abordar os conceitos sobre polimorfismo e sua implementação e utilização na linguagem Visual Basic desta vez mostrando o polimorfismo em tempo de compilação que utiliza a sobrecarga de métodos e operadores sendo também chamado de ligação precoce.