Irei iniciar uma série de artigos com o objetivo de apresentar os conceitos básicos da programação orientada a objetos aplicados à linguagem Visual Basic .NET.
O objetivo do curso é proporcionar um bom conhecimento sobre Programação Orientada a Objetos, ensinar como as técnicas orientadas a objetos são usadas no VB.NET e explicar os principais conceitos da orientação a objetos de forma simples e prática.
Neste minicurso iremos abordar os seguinte assuntos:
- Namespaces, Classes e Objetos e Módulos
- Tipos de Acessos (Public, Private, Protected)
- Funções estáticas (Shared)
- Sobrecarga (Overloading)
- Herança (Inherits)
- Sobreposição (Overriding)
- Classes Abstratas (MustInherit)
- Construtores e Destrutores (Sub New/ Finalize)
- Propriedades (ReadOnly, WriteOnly)
- Interfaces (Interface)
- Polimorfismo (Overridable, Overrides)
- Como criar e utilizar classes e objetos no VB .NET (Class, New)
- Exemplos práticos
Para acompanhar os artigos do curso você deverá possuir instalado a(s) seguinte(s) ferramenta(s):
- Microsoft Visual Studio Express 2010 (ou superior)
Bom estudo!
Lição 1 – Namespaces, Classes e Objetos e Modulos
- Namespace
No VB.NET, classes e outras estruturas de dados para um propósito específico são agrupados para formar um namespace.
Você pode usar as classes em um namespace, simplesmente importando-o.
A palavra-chave Imports é usada para importar um namespace para o seu projeto. O .NET Framework. fornece um rico conjunto de classes agrupadas em vários namespaces. Nesta lição, estamos usando o namespace System.
Importe o namespace System (já disponível em. NET).
Imports System
- Classe
Uma classe é uma definição de um objeto real.
Por exemplo: Humano é uma classe que representa todos os seres humanos. Cachorro é uma classe que representa todos os cachorros.
Em uma definição mais técnica, podemos dizer que Classes são pacotes de dados e comportamentos relacionados que podem conter atributos, métodos e eventos.
No VB .NET podemos resumir a sintaxe usada na declaração de uma classe da seguinte forma:
[ atributo ] [Partial] [ accessibility ] [Shadows] [ inheritance ] _ Class name [(Of type_list )] [Inherits classe_pai ] [Implements interface ] statements End Class
Vejamos as principais declarações usadas.
Para começar, podemos dizer que de todas as declarações usadas acima, as únicas que são obrigatórias para todas as classes são:
- A cláusula Class name, que identifica uma classe e lhe dá um nome;
- A declaração End Class, que indica o fim da classe. A classe pode ser declarada vazia – sem métodos, propriedades ou eventos – e mesmo assim continuar válida;
Com base nisso, uma classe obrigatoriamente teria que usar no mínimo a seguinte sintaxe ao ser declarada:
Class name ...... End Class
Uma classe pode possuir membros como: campos, propriedades, métodos: sub-rotinas e funções.
Nota: O VB .NET fornece funções e sub-rotinas. As Funções sempre retornam um valor e uma sub-rotina não pode retornar um valor.
Assim podemos ter:
- Um namespace Animais;
- A classe Cachorro no namespace Animais;
- A sub-rotina (método) Latir() na classe Cachorro;
- Objeto
Um objeto é uma instância de uma classe. Uma classe é um modelo de uma entidade que a classe representa. Para usar um campo, método ou qualquer outro membro de uma classe, você vai precisar tornar a classe em um objeto.
Na linguagem OOP, um objeto é uma instância de uma classe; assim, para criar um objeto, temos que instanciá-lo a partir de uma classe (A classe é um conceito, o que existem são os objetos).
No VB .NET podemos criar uma instância de uma classe de duas formas:
Forma direta:
Dim objetoCachorro As New Animais.Cachorro
Forma indireta:
Dim objetoCachorro As Animais.Cachorro objetoCachorro = New Animais.Cachorro
- Na primeira forma declaramos a variável objeto objetoCachorro como um objeto da classe Cachorro com a palavra New;
- Na segunda forma declaramos a variável objeto do tipo Cachorro e instanciamos o objeto com a palavra New;
- Módulos
Os módulos da linguagem Visual Basic .NET fornecem uma maneira simples de testar pequenos trechos de códigos. Em aplicações de produção, os módulos são menos usados do que as classes mas não deixam de ter sua utilidade para ilustrar conceitos importantes. Como as classes e os formulários, os módulos são definidos em arquivos fontes que possuem a extensão .vb.
Você usa um módulo para criar um container para variáveis, procedimentos e funções usados em toda a aplicação e, em alguns casos, para fornecer o método que funciona como um ponto de entrada para a aplicação.
Sintaticamente falando, um bloco de módulo esta delimitado pelas palavras chaves Module e End Module e podem conter constantes públicas ou privadas, campos, propriedades e métodos.
Você pode usar módulos para escrever funções comuns. Um módulo é um grupo de funções. Ao contrário das funções nas classes, as funções públicas em módulos podem ser chamadas diretamente a partir de qualquer outro lugar do projeto.
O método Main é o ponto de entrada pra todas as aplicações do tipo console e opcionalmente para as aplicações do tipo Windows forms.
Na sua forma mais simples, o método Main é um procedimento do tipo Sub que não usa argumentos.
- Temos o módulo Module_OOP e o método Main();
- No método Main() criamos uma variável objeto pipoca como uma instância da classe Cachorro;
- pipoca passa a ser um objeto do tipo Cachorro e possui o método Latir().
Lição 2 – Tipos de acessos
Ao escrever suas classes, você pode ou não querer que outras pessoas acessem sua funcionalidade acessando suas propriedades e chamando seus métodos.
Na OOP podemos restringir o acesso a um membro de uma classe e ter assim mais controle sobre o conteúdo da classe.
Você é quem decide se vai permitir que outras pessoas acessem os métodos e propriedades da sua classe ou se o acesso somente poderá ser feito a partir da sua própria classe.
O VB.NET oferece os seguintes níveis de acesso:
- Public – Os membros da classe não possuem qualquer restrição e podem ser acessados por qualquer programa;
- Private – Os membros somente podem ser acessados a partir da própria classe;
- Protected – Os membros são acessíveis a partir da própria classe e das classes derivadas;
- Friend – Os membros são acessíveis somente dentro do programa que possuem a declaração da classe;
- Protected Friend – Os membros são acessados somente pelo código de dentro do projeto e pelo código na classe derivada;
- NotInheritable (Sealed) – O modificador NotInheritable faz com que a classe não possa ser herdada.
- Importamos o namespace System (com isso não precisamos mais declarar a classe Console);
- Definimos três variáveis na classe Cachorro: duas públicas e uma privada;
- Definimos o método Private AbanarRabo();
- Definimos o método IsVacinado() como Friend;
- O campo raça e o método AbanarRabo() são acessíveis somente a partir da própria classe.
Quando colocamos os dados e métodos (sub-rotinas e funções) em uma classe, temos o que é conhecido como Encapsulamento.
Normalmente, em uma classe, as variáveis utilizadas para armazenar dados (como a idade de um cão) são declaradas como Private.
Funções ou propriedades são usadas para acessar essas variáveis. Proteger os dados de um objeto do acesso às funções fora da classe é chamado de abstração ou ocultamento de dados. Isso impede a modificação acidental ou mal intencionada de dados por funções externas.
Para poder ter acesso ao campo idade, podemos definir a propriedade Publica IdadeCachorro na classe Cachorro que permite acessar e atribuir valor a variável idade:
Public Property IdadeCachorro() As Integer Get Return idade End Get Set(ByVal Value As Integer) idade = Value End Set End Property
Para definir uma propriedade somente leitura removemos os comandos Set/End Set
Public Property IdadeCachorro() As Integer Get Return idade End Get End Property
Nota: A partir o VS 2010 podemos usar no VB .NET as propriedades auto-implementadas.
Lição 3 – Funções estáticas (Shared)
De forma geral, para poder ter acesso as propriedades e métodos da classe, temos que criar uma instância da classe.
Os membros compartilhados ou shared de uma classe (funções e variáveis) podem ser usados sem ter que criar objetos da classe.
O modificador Shared indica que o método não funciona em uma instância específica de um tipo e pode ser chamado diretamente a partir de um tipo e não através de uma instância específica de um tipo.
Com isto concluímos que membros declarados como Shared são membros da classe e não membros de instância e podemos acessar membros declarados como Shared em uma classe sem criar uma instância da classe.
Nota: O equivalente na linguagem C# seria a palavra chave static.
O método Comer() e a variável tamanho foram declaradas como Shared e poderão ser acessados diretamente sem termos que criar uma instância da classe, conforme mostramos no exemplo abaixo:
O .NET Framework possui muitas classes Shared, como exemplo podemos citar a classe System.Math.
Lição 4 – Sobrecarga (Overloading)
Sobrecarga ou Overloading; o que é isso? Se você está vindo de uma linguagem procedural como Clipper, Dbase, Basic ou se está começando agora, tendo o VB como sua primeira linguagem de programação, pode estranhar o termo. Mas é apenas uma questão de prática.
Sobrecarga é a habilidade de poder definir diversas propriedades, métodos ou procedimentos em uma classe com o mesmo nome. Deu pra entender? Bem, vou ser mais claro: se você criar dois métodos em seu aplicativo com o mesmo nome e com argumentos diferentes, estará usando sobrecarga.
Você deve estar se perguntando: “como posso criar dois métodos com o mesmo nome? Como vou diferenciá-los?”. Garoto ‘experto’ você! Você vai diferenciar os procedimentos pela lista de argumentos que eles vão possuir; isto é, os métodos terão argumentos diferentes.
Vou dar um exemplo: suponha que você precise criar uma classe com um método que retorne o valor da área de um quadrado, só que este método vai poder aceitar como parâmetro uma string ou um número:
Temos dois métodos Calcula_Area() que usam argumentos com tipos diferentes: Double e String. Neste caso, os métodos são ditos sobrecarregados.
Podemos também usar a palavra-chave Overloads ao criar métodos sobrecarregados. Ela é opcional,mas se você usar em um método terá que usar nos demais.
- A lista de argumentos deve ser diferente em métodos sobrecarregados. Você não pode ter dois métodos onde cada um tenha um argumento do mesmo tipo de dados e apenas o nome do argumento diferente.
Public Function Calcula_Area(ByVal l As Double) As Double Public Function Calcula_Area(ByVal lado As Double) As Double
Você não pode ter métodos sobrecarregados, diferenciados apenas por um argumento Optional:
Public Overloads Function GetNomeCompleto(ByVal nome As String) Public Overloads Function GetNomeCompleto(ByVal nome As String, Optional ByVal sobrenome As String = "")
Você não pode ter métodos sobrecarregados diferenciados apenas pelo tipo de retorno:
Public Overloads Function GetNomeCompleto(ByVal nome As String) As String Public Overloads Function GetNomeCompleto(ByVal nome As String) As Boolean
Lição 5 – Herança
Herança é um conceito chave usado na programação orientada a objetos para descrever uma relação entre as classes. Por meio da herança uma classe copia ou herda todas as propriedades, atributos e métodos de uma outra classe, podendo assim estender sua funcionalidade.
A classe que cede os membros para a outra classe é chamada superclasse, classe pai ou classe base. A classe que herda os membros da outra classe é chamada subclasse ou classe derivada.
A herança permite a reutilização de código e especifica um relacionamento de especialização/generalização do tipo “é um”.
Embora seja um recurso poderoso, a herança deve ser usada somente quando necessário, pois pode levar a um acoplamento forte entre as classes do seu projeto, dificultando a sua reusabilidade e a manutenção;
Existe a herança de implementação onde uma classe derivada herda da classe base e a herança de interface onde uma classe pode herdar de uma interface. Neste caso, apenas as assinaturas dos métodos são herdados, sendo que os métodos devem ser implementados.
No VB.NET usamos a declaração inherits para implementar a herança. O VB.NET não suporta herança múltipla, assim uma classe derivada pode ter uma única classe base.
Classe A – classe Base (Pai)
Public Class A Public a As Integer Public Sub New() Console.WriteLine("construtor A") End Sub Public Sub M(nome As String) Console.WriteLine("sou o " & nome) End Sub End Class
Classe B (Filha) que herda da classe A
Public Class B Inherits A Private b As Integer Public Sub New() Console.WriteLine("construtor B") End Sub Public Sub J() Console.WriteLine("sou J ") End Sub End Class
- A subclasse B herda a variável a e o método M(string nome) e inclui a variável b e o método J();
- O construtor sem parâmetros A() da classe base A é herdado;
- O construtor da subclasse sempre chama o construtor da classe base e depois executa o seu próprio código;
- Uma classe somente pode herdar de uma classe; Não existe herança múltipla;
- Uma classe pode implementar múltiplas interfaces;
- Toda a classe é derivada da classe Object; A classe Object não deriva de nenhuma classe; Ela é a classe Base (Pai) de todas as classes;
- Uma classe somente pode herdar de outra classe; Uma classe não pode herdar de uma struct;
- Os métodos herdados de uma classe Base podem ser sobrescritos, para isso eles devem ser definidos com a palavra-chave Overridable;
- Para sobrepor um método da classe base use a palavra-chave overrides.
O modificador de acesso protected torna a variável de uma classe base somente acessível às suas classes derivadas (outras classes não acessam a variável).
Métodos herdados de System.Object:
- Equals – Testa se dois objetos são iguais;
- GetHashCode – Retorna o código de hash para o objeto;
- GetType – Retorna informação sobre a classe do objeto;
- ToString – Retorna o objeto como string.
Todas as classes declaradas podem ser herdadas. Se você não quer permitir que uma classe seja herdada inclua na declaração da classe a palavra-chave: NotInheritable.
Para impedir que uma classe seja herdada, usamos o modificador MustInherit. Este modificador faz com que uma classe seja destinada apenas a servir como base para a criação de outras classes.
Desta forma não é possível criar instâncias diretas desta classe (chamamos isto de classe abstrata em C#).
Lição 6 – Sobreposição (Overriding)
Por padrão, uma classe derivada herda os métodos de sua classe base. Se uma propriedade herdada ou método precisa se comportar de forma diferente na classe derivada ele pode ser substituído, ou seja, você pode definir uma nova implementação do método na classe derivada.
No VB.NET indicamos que um método é passível de sobreposição usando a palavra-chave Overridable na classe pai (classe base) e a seguir, na classe filha, declaramos novamente o método com a palavra-chave Overrides. Assim temos que:
- Overridable – declara que o método pode ser sobreposto nas classes que herdarem da classe base;
- Overrides – indica que o método da classe filha irá sobrepor o método da classe pai.
Classe Pai
Public Class Pessoa Public Overridable Sub profissao() Console.Write("Eu sou um engenheiro.") End Sub End Class
Classe Filho
Class Funcionario : Inherits Pessoa Public Overrides Sub profissao() Console.Write("Eu sou funcionário do governo.") End Sub End Class
- A classe pai está usando o modificador Overridable no método Profissão;
- A classe filha – Funcionário – herda o método – Profissão. O modificador Overrides indica que a classe sobrepõe a classe herdada.
O método Profissão na classe – Funcionário – irá sobrepor o método herdado da classe pai. Para que um método da classe pai não possa ser sobreposto usamos o modificador – NotOverridable.
Já, para definir que um método seja obrigatoriamente sobreposto em uma classe filha, usamos a palavra-chave – MustOverride.
Na próxima aula irei abordar os conceitos da programação orientada a objetos como polimorfismo, construtores, destrutores e propriedades.