.NET - Trabalhando com objetos


 

Visual Basic .NET e Visual C# provê um ambiente repleto de conceitos de programação orientada a objetos, incluíndo classes abstratas, interfaces e membros de classes overloading ou overriding. Estes conceitos são fundamentais para a linguagem e são usadas por todo Microsoft .NET Framework.

 

Nota: Veja também os seguintes artigo do site sobre o assunto:

 

VB.NET - Revisitando conceitos OOP - Relembrando conceitos básicos da programação OOP no VB.NET.
.NET - Conceitos da programação POO  - Métodos e variáveis shared ; Classes internas (inner class) ; o método Main() e criando uma classe Singleton.
VB .NET - Primeiros passos - Conceitos - VI.  -
Conceitos OOP para você : sobrecarga , sobreposição , classes abstratas e interfaces.

VB .NET - Primeiros passos - Conceitos - V  -
Orientação a objeto no VB .NET : classes , propriedades , métodos ; instanciando um objeto ; construtor , herança.
VB .NET - Primeiros passos - Conceitos - IV -
Escrevendo sua aplicação VB .NET com os conceitos apresentados. Calculando o valor futuro:passo a passo.
VB .NET - Primeiros passos - Conceitos - III -
Os conceitos básicos para começar a escrever código VB .NET ; Escrevendo suas próprias rotinas e funções e escopo de variáveis
VB .NET - Primeiros passos - Conceitos - II -
Os conceitos básicos para começar a escrever código VB .NET ; operações e funções básicas
VB .NET - Primeiros passos - Conceitos - I - Os conceitos básicos para começar a escrever código VB .NET (ideal para iniciantes e iniciados) ; variáveis , constantes , vetores.
VB .NET  - Conceitos OOP.  -
Qual a diferença entre classe e objeto ? O que é um variável/membro de classe ?

 

Através deste artigo aprenderemos:

 

- a organizar nosso código usando namespaces;

- os conceitos chaves de orientação a objetos.

 

Entendendo Namespaces

 

Você já deve ter notado que no começo do código de cada Web Form são gerados alguns códigos automaticamente, como este:

 

Visual Basic .NET

Imports System

Imports System.Web

Visual C#

using System;

using System.Web;

 

Este artifício permite que usemos código do namespace System e System.Web sem a necessidade de especificar todo seu caminho.

Por exemplo, o método Array, com a referência indica acima, podemos escrever apenas:


Array.Sort(strArray);    ao invés de    System.Array.Sort(strArray);

 

Portanto, namespaces (referências) são um meio de organizar o código.

 

Segue forma genérica de uso do namespace:    ProjectName.NameSpace.ModuleName.MemberName

 

Inclusive você pode criar seu próprio namespace. Veja um exemplo:

 

Visual Basic .NET Visual C#

 

' Project name: WebAppsVB

Namespace Utils

    Public Module Strings

        Public Function Sort(ByVal strText As String, _

            Optional ByVal bAlphaOrder As Boolean = True) As String

            ' Declare and initialize a string array.

            Dim strArray As String() = {""}

            ' Convert the string to an array using System.String.

            strArray = strText.Split(" ")

            ' Use System.Array to sort.

            System.Array.Sort(strArray)

            ' If it's not alphabetic order, reverse the array.

            If Not bAlphaOrder Then

                ' Use System.Array to reverse.

                System.Array.Reverse(strArray)

            End If

            ' Return the a string.

            Sort = System.String.Join(" ", strArray)

        End Function

    End Module

End Namespace

 

 

// Project name: WebAppsCS

namespace Utils

{    class Strings

    {

        // Takes a string, sorts it, and returns a string.

        public static string Sort(string strText , bool bAlphaOrder)

        {

            // Declare and initialize a string array.

            string[] strArray = {""};

            char[] strSep = {' '};

            //  Convert the string to an array using System.String.

            strArray = strText.Split(strSep);

            // Use System.Array to sort.

            System.Array.Sort(strArray);

            //  If it's not alphabetic order, reverse the array.

            if (!bAlphaOrder)

            {

                // Use System.Array to reverse.

                System.Array.Reverse(strArray);

            }

            // Return the string.

            return System.String.Join(" ", strArray);

        }

        // Same method with one parameter.

        public static string Sort(string strText)

        {

            return Sort(strText, true);

        }        

    }

}

 

 

 

Classes e Módulos
 

Visual Basic .NET e Visual C# usam 6 conceitos chaves para trabalhar com classes e módulos. Estes conceitos são novos para o Visual Basic, e claro, Visual C#, porque se trata de uma linguagem totalmente nova. Entretanto, programadores C++ já deveriam estar familiarizados com estes conceitos.
 

Segue tabela com os conceitos:

Conceito

Visual Basic .NET

Visual C#

Definition

Você define se algo é uma classe ou módulo, usando os blocos Class...End Class ou Module...End Module.

Você define uma classe usando a palavra chave class. Todo código executável faz parte da classe.

Access

Existem 5 níveis de acesso a classes, módulos e seus membros: Public, Protected, Friend, Protected Friend, e Private.

Existem 5 níveis de acesso a classes e seus membros: public, protected, internal, protected internal, e private.

Inheritance

Classes podem herdar membros de outras; e sobreescrever (override), esconder (shadow) ou sobrecarregar (overload) membros da classe herdada.

Classes podem herdar membros da classe básica e sobreescrever (override) ou sobrecarregar (overload) membros da classe herdada.

Constructors and destructors

Classes possuem os métodos New e Finalize que são chamados quando um objeto base da classe é criado ou destruído.

Classes possuem constructors e destructors que são chamados quando um objeto base da classe é criado ou destruído. Constructors têm o mesmo nome de sua classe e destructors usam o nome da classe precedido pelo sinal (~)

Delegates

A declaração Delegates provê uma forma segura de chamar métodos pelo seu endereço ao invés de chamar pelo nome. Isto é o equivalente a Callback. Delegates são comumente usados com eventos a procedimentos assíncronos.

A palavra chave Delegates provê uma forma segura de chamar métodos pelo seu endereço ao invés de chamar pelo nome. Isto é o equivalente a Callback. Delegates são comumente usados com eventos a procedimentos assíncronos.

Abstract classes and interfaces

Você pode criar interfaces e classes abstratas. Interfaces definem os nomes dos membros e a lista de parâmetros dos membros da classe que usa a interface. Classes abstratas provêem os membros para serem herdados por classes derivadas dela.

Você pode criar interfaces e classes abstratas. Interfaces definem os nomes dos membros e a lista de parâmetros dos membros da classe que usa a interface. Classes abstratas provêem os membros para serem herdados por classes derivadas dela.

 

Criando classes/módulos e provendo acessos

 

Em Visual Basic .NET use o bloco Class…End Class e Module…End Module para definir classes e módulos. Em Visual C# use a palavra chave class para definir classes. Você pode ter uma ou mais classes e/ou módulos por arquivo. Use uma das palavras chave de acesso descritas na tabela abaixo para definir qual classe ou módulo pode usar membros da corrente classe ou módulo.

 

Visual Basic

Visual C#

Válido para

Public

public

Todos os membros em todas as classes e projetos.

Friend

internal

Todos os membros no corrente projeto.

Protected

protected

Todos os membros na classe corrente e em classes derivadas desta classe de membros. Pode ser usada somente em definições de membro, não para definições de classes ou módulos.

Protected Friend

protected internal

Todos os membros no projeto corrente e em todos os membros em classes derivadas desta classe de membros. Pode ser usada somente em definições de membro, não para definições de classes ou módulos.

Private

private

Membros da classe corrente somente.

 

Por exemplo, a seguinte classe é válida somente no projeto corrente:

 

Visual Basic .NET

Visual C#

Friend Class Translator

    Private mstrText As String

    ' Controls access to the class-level

    ' variables.

    Public Property Text() As String

        Get

            Text = mstrText

        End Get

        Set(ByVal Value As String)

            mstrText = Value

        End Set

    End Property

    ' Translates the value in the Text property.

    Public Sub Translate()

        Dim strWord As String, intCount As Integer

        Dim arrWords() As String

        Dim bCaps As Boolean

        ' Convert the string to an array using System.String.

        arrWords = mstrText.Split(" ")

        For intCount = 0 To UBound(arrWords)

            ' Check if word is capitalized.

            If LCase(arrWords(intCount)) <> arrWords(intCount) Then

                bCaps = True

                arrWords(intCount) = LCase(arrWords(intCount))

            End If

            strWord = arrWords(intCount)

            ' Do translation.

            If strWord <> "" Then

                strWord = Right(strWord, Len(strWord) -  1) & _

                  Left(strWord, 1) & "ay"

                ' Recapitalize if necessary

                If bCaps Then

                    strWord = UCase(Left(strWord, 1)) & _

                      Right(strWord, Len(strWord) - 1)

                End If

            End If

            ' Store back in the array.

            arrWords(intCount) = strWord

            ' Reset caps flag.

            bCaps = False

        Next

        ' Rebuild string from array.

        mstrText = String.Join(" ", arrWords)

    End Sub

End Class

 

internal class Translator

{

        string mstrText;

        // Controls access to class-level variables.

        public string Text

        {

            get

            {

                return mstrText;

            }

            set

            {

                mstrText = value;

            }

        }

        // Translates the value in the Text property. 

        public void Translate()

        {

            string strWord;

            string[] arrWords;

            bool bCaps = false;

            //  Convert the string into an array using System.String.

            arrWords = mstrText.Split(' ');

            for(int intCount = 0; intCount <= arrWords.GetUpperBound(0); 

                 intCount++)

            {

                // Change to lowercase.

                strWord = arrWords[intCount].ToLower();

                // Check if word is capitalized.

                if(!arrWords[intCount].Equals(strWord))

                    bCaps = true;

                // Do translation.

                if(strWord != "")

                {

                    strWord = strWord.Substring(1,strWord.Length - 1) +

                      strWord.Substring(0,1) + "ay";

                    // Recapitalize if necessary.

                    if(bCaps)

                        strWord = strWord.Substring(0,1).ToUpper() +

                          strWord.Substring(1, strWord.Length - 1);

                }

                // Store the word back in the array.

                arrWords[intCount] = strWord;

                // Reset the caps flag.

                bCaps = false;

            }

            // Rebuild the string from the array.

            mstrText = String.Join(" ", arrWords);

        }

}

 

 

 

Você pode acessar a propriedade Text o método Translate da classe Translator de dentro do projeto onde ela está incluída, mas não de outros projetos.

 

E para finalizar, o código abaixo mostra como usar a propriedade e o método em um Web Form:

 

Visual Basic .NET

Visual C#

Private Sub butTranslate_Click(ByVal sender As System.Object , _

  ByVal e As System.EventArgs) Handles butTranslate.Click

     ' Create a new Translator object.

    Dim TranslateText As New Translator()

    ' Put the source text into the translator.

    TranslateText.Text = txtInput.Text    ' Turn the crank.

    TranslateText.Translate()

    ' Display result.

    txtOutput.Text = TranslateText.Text

End Sub

private void butTranslate_Click(object sender, System.EventArgs e)

{

    // Create a new Translator object.

    Translator TranslateText = new Translator();

    // Put the source text into translator.

    TranslateText.Text = txtInput.Text;

    // Turn the crank.

    TranslateText.Translate();

    // Display the result.

    txtOutput.Text = TranslateText.Text;

}

 

 

Inheritance (Herança)

 

Inheritance é o processo em que uma classe é baseada em outra. Neste processo, a classe básica provê métodos, propriedades e outros membros para a classe derivada. A vantagem da herança é que você pode escrever e manter o código, uma vez que está na classe básica, podendo reutilizar o código nas classes derivadas.

 

Em Visual Basic .NET você usa o indicativo Inherits para basear uma nova classe em outra. Em Visual C# nenhuma palavra chave é necessária; usamos somente a definição de classe. As seguintes linhas mostram as sintaxes para cada linguagem:

 

Visual Basic .NET

Public Class DerivedClass

    Inherits BaseClass

End Class

Visual C#

public class DerivedClass : BaseClass

{

}

 

 

VS.NET usa as palavras chaves descritas na tabela abaixo para criar classes bases e para derivar novas classes delas.

 

Visual Basic

Visual C#

Usar para

Inherits

derivedclass : baseclass

Baseia uma classe em outra, herdando membros da classe básica.

Overridable

virtual

Declara que um membro da classe básica pode ser sobreescrita em uma classe derivada.

Overrides

override

Declara que um membro de uma classe derivada sobreescreve um membro de mesmo nome na classe básica.

Shadows

new

Declara que um membro de uma classe derivada esconde o membro de mesmo nome na classe básica.

MustInherit

abstract

Declara que uma classe provê um modelo (template) para uma classe derivada. Este tipo de classe é chamada classe abstrata e não pode ser instanciada.

MustOverride

abstract

Declara que um membro de uma classe provê um modelo (template) para membros derivados. Este tipo de membro é chamado membro abstrato e não pode ser invocado.

MyBase

base

Chama um membro de um classe básica de dentro de uma classe derivada.

Me

this

Chama um membro de uma instância corrente da classe.

Interface

interface

Cria uma interface que define os membros que uma classe deve prover.

Implements

classname : interfacename

Usa uma definição de interface na classe.

 

Abstract

 

VS.NET permite que você também defina classes abstratas. Uma classe abstrata é uma classe que define uma interface para uma classe derivada. Você não pode criar objetos de classes abstratas, você pode apenas derivar novas classes dela.


Classes abstratas são declaradas com as palavras chaves MustInherit (em VB.NET) e abstract (em C#).


A seguinte classe Shape demonstra uma classe abstrata:

 

Visual Basic .NET

' Definition of abstract class.

Public MustInherit Class Shape

    Public MustOverride Property Top() As Single

    Public MustOverride Property Left() As Single

    Public MustOverride Function Area() As Single

    Public MustOverride Function Perimeter() As Single

End Class

Visual C#

// Definition of abstract class.

public abstract class Shape

{

    public Shape()

    {

    }

    public abstract float Top

    {

        get;

        set;

    }

    public abstract float Left

    {

        get;

        set;

    }

    public abstract float Area();

    public abstract float Perimeter();

}

 

P.S.: Note que os membros MustInherit (VB.NET) e abstract (C#) são apenas definições – não há definição de corpo do procedimento porque estes membros serão definidos (overridden) na classe derivada.

 

Delegates

 

Delegates são tipos usados para invocar um ou mais métodos onde o método atual invocado é determinado em tempo de execução. Delegates provê uma forma de invocar método pelo seu endereço ao invés de seu nome.

 

Por exemplo, o seguinte Web Form code declara um delegate chamado MathDelegate e invoca dois diferentes métodos através da procedure AboutNumber. Quando executado, este código apresenta a mensagem : The number 42 is even and is not prime.

 

Visual Basic Visual C#

Public Class SimpleDelegate

    Inherits System.Web.UI.Page

    ' Declare a delegate.

    Delegate Function MathDelegate(ByVal x As Integer) As Boolean

  Private Sub Page_Load(ByVal sender As System.Object, _

  ByVal e As System.EventArgs) Handles MyBase.Load

        Dim MyNumber As Integer = 42

        Response.Write("<h2>Using Delegates</h2><hr />")

        Response.Write("The number " & MyNumber.ToString())

        ' Call AboutNumber to invoke IsEven. 

        AboutNumber(AddressOf IsEven, MyNumber)

        Response.Write(" even and it ")

        ' Call AboutNumber to invoke IsPrime.

        AboutNumber(AddressOf IsPrime, MyNumber)

        Response.Write(" prime.")

    End Sub

    ' Invoke the delegate.

    Sub AboutNumber(ByVal Func As MathDelegate, ByVal x As Integer)

        If Func.Invoke(x) Then

            Response.Write(" is ")

        Else

            Response.Write(" is not ")

        End If

    End Sub

    ' These procedures may be invoked through MathDelegate.

    Function IsEven(ByVal x As Integer) As Boolean

        If x Mod 2 Then

            Return False

        Else

            Return True

        End If

    End Function

    Function IsPrime(ByVal x As Integer) As Boolean

        Dim i As Integer

        For i = 2 To x \ 2

            If (x Mod i = 0) Then

                Return False

            End If

        Next

        Return True

    End Function

End Class

public class SimpleDelegate : System.Web.UI.Page

{

    delegate bool MathDelegate(int x);

    private void Page_Load(object sender, System.EventArgs e)

    {

        int MyNumber  = 42;

        Response.Write("<h2>Using Delegates</h2><hr />");

        Response.Write("The number " + MyNumber.ToString());

        // Call AboutNumber to invoke IsEven. 

        AboutNumber(new MathDelegate(IsEven), MyNumber);

        Response.Write(" even and it ");

        // Call AboutNumber to invoke IsPrime.

        AboutNumber(new MathDelegate(IsPrime), MyNumber);

        Response.Write(" prime.");

    }

    // Invoke the delegate.

    void AboutNumber(MathDelegate Func, int x)

    {

        if (Func(x)) 

            Response.Write(" is ");

        else

            Response.Write(" is not ");

    }

    // These procedures may be invoked through MathDelegate.

    bool IsEven(int x ) 

    {

        if (x % 2 == 0) 

            return true;

        else

            return false;

    }

    bool IsPrime(int x )

    {

        for(int i = 2; i > (x /2); i++)

            if (x % i == 0) 

                return true;

        return false;

    }

}

 

Interfaces

 

Interfaces são similares a classes abstratas no sentido de que ambas provêem um modelo (template) que você pode usar para criar novas classes. A diferença é que interfaces não provêem qualquer implementação dos membros da classe, por outro lado classes abstratas podem implementar membros que então se tornam comuns para todas as classes derivadas dela.

 

Quando você implementa uma interface em uma classe, instâncias desta classe podem ser usadas por qualquer argumento ou variável declarada nesta interface. Por exemplo, o seguinte código declara uma interface para o objeto Shape:

 

Visual Basic .NET

Visual C#

' Interface for all shapes.

Public Interface IFigure

    Property Top() As Single

    Property Left() As Single

    Function Area() As Single

    Function Perimeter() As Single

End Interface

 

 

// Interface for all shapes.

public interface IFigure

{

    float Top

    {

        get;

        set;

    }

        float Left

    {

        get;

        set;

    }

        float Area();

        float Perimeter();

}

 

Para usar a interface, implemente-a na classe, como mostrada em negrito:
 

Visual Basic .NET Visual C#

 Definition of abstract class.

Public MustInherit Class Shape

    Implements IFigure

    Public MustOverride Property Top() As Single Implements IFigure.Top

    Public MustOverride Property Left() As Single Implements  IFigure.Left

    Public MustOverride Function Area() As Single Implements  IFigure.Area

    Public MustOverride Function Perimeter() As Single Implements _ 

       IFigure.Perimeter

End Class

 

public abstract class Shape IFigure

{

    // Constructor

    public Shape()

    {

    }

    public abstract float Top

    {

        get;

        set;

    }

        public abstract float Left

    {

        get;

        set;

    }

    public abstract float Area();

    public abstract float Perimeter();

}

 

Obs: Artigo enviado a título de colaboração, aguardando identificação do autor.

 


José Carlos Macoratti