NUNCA MAIS PASSE RAIVA POR NÃO CONSEGUIR RESOLVER UM PROBLEMA COM O EXCEL - GARANTIDO!

UNIVERSIDADE DO VBA - Domine o VBA no Excel Criando Sistemas Completos - Passo a Passo - CLIQUE AQUI

Você está em: PrincipalArtigosASP.NET › Capítulo 04 : 03
Quer receber novidades e e-books gratuitos?
  « Lição anterior Δ Página principal ¤ Capítulos Próxima lição »
ASP.NET - CURSO COMPLETO
Autor: Júlio Battisti

Lição 034 - Capítulo 04 - Classes

O conceito de Classes é fundamental para a orientação a objetos. Como o Framework .NET é fortemente baseado nos conceitos de orientação a objetos é óbvio que o conceito de Classes é igualmente importante para o Framework .NET.

Para sair do discurso teórico e partir para a prática basta analisar os exemplos que apresentamos até o momento. Não houve um único exemplo em que não utilizamos pelo menos uma classe do .NET Framework Class Library (biblioteca de classes do .NET). Conforme já havíamos salientado,  a biblioteca de classes do .NET nos oferece uma infinidade de classes que podem ser utilizadas em nossos programas e páginas.

Através da utilização de classes estamos viabilizando, na prática, os princípios da herança e da reutilização de código. Ao criarmos uma classe estamos, na verdade, definindo as características de um novo objeto. A definição da classe contém os métodos, propriedades, indexadores (novidade no .NET) e Eventos da classe. Também contém informação sobre a visibilidade dos elementos da classe. A visibilidade define, por exemplo, se um método da classe somente poderá ser utilizado por outros métodos da própria classe ou poderá ser utilizado externamente à classe.

Uma vez definida a classe podemos utilizá-la em nossos programas e páginas. Para utilizar uma classe criamos e instanciamos um objeto como sendo do tipo definido pela classe. A partir deste momento o objeto passa a ter acesso a todos os elementos – métodos, propriedades, etc, da classe. Em outras palavras: o objeto herda todos os elementos da classe.

Neste capítulo aprenderemos a criar e utilizar classes no C#. Também aprenderemos a criar os diversos elementos que compõem uma classe.

Para começar, um exemplo simples:

Vamos aprender sobre a estrutura de uma classe criando uma. Criaremos uma classe extremamente simples. Daremos o nome de ClasseEx1. O único componente que a nossa classe irá conter será a definição de duas variáveis: um inteiro e uma string. No programa principal iremos criar uma instância da classe e utilizar as variáveis da mesma.

Considere o exemplo da Listagem 4.3.

Listagem 4.3 – Uma classe bastante simples. – Ex4Cap4.cs

using System;
class ClasseEx1
{
            //Definição  dos membros da classe.
            public int  contador = 0;
            public  string teste = " ";
}
class Ex3cap4
{
            // Exemplo  3 - Capítulo 4.
            // Criação  de uma classe com dois membros.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public  static void Main()
            {
                        //  Agora crio uma variável do tipo ClasseEx1.
                        //  Esta variável é uma instância da classe ClasseEx1.
                        ClasseEx1  minhaclasse = new ClasseEx1();            
                        //Definição  de novos valores para os membros da classe.
                        minhaclasse.contador  = 125;
                        minhaclasse.teste    = "PRIMEIRA CLASSE COM O C#";
                        //Agora  exibo os resultados.
                        Console.WriteLine("**************************************************");
            Console.WriteLine("VALOR  DO MEMBRO INTEIRO: {0}",minhaclasse.contador);
            Console.WriteLine("VALOR  DO MEMBRO STRING:   {0}",minhaclasse.teste);
            Console.WriteLine("**************************************************");                
            }
}

Digite o exemplo da listagem 4.3 e salve o mesmo em um arquivo chamado ex3cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.3. Você obterá os resultados indicados na Figura 4.4.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.4 Executando o programa ex3cap4.exe.

Temos vários detalhes importantes a considerar neste exemplo.

Em primeiro lugar a definição da classe ClasseEx1, a qual é feita no seguinte trecho de código. Para definir uma nova classe utilizamos a palavra class. A definição dos elementos da classe acontece dentro do abre e fecha chaves { }.

class ClasseEx1
{
            //Definição  dos membros da classe.
            public int  contador = 0;
            public  string teste = " ";
}

Neste exemplo definimos dois campos:

  • contador
  • teste

Estes campos, também chamados de membros da classe (na verdade membro é qualquer elemento da classe, quer seja uma propriedade, um campo, um método, etc). A palavra public faz com que estes campos possam ser acessados fora da classe, isto é, dentro do código do programa que estiver utilizando a classe.

Após a definição da classe temos uma segunda classe, chamada Ex3cap4.

class Ex3cap4

Esta é a classe principal do nosso exemplo, a qual conterá uma função Main(). Dentro da função Main( ) criamos um objeto chamado minhaclasse. Observe que este objeto é definido como sendo do tipo da classe criada anteriormente, ou seja, o objeto minhaclasse é baseado na classe ClasseEx1. A declaração e instanciação da variável objeto minhaclasse é feita na seguinte linha de código:

ClasseEx1 minhaclasse = new ClasseEx1();             

Neste caso a novidade é o uso do operador new para a instanciação do objeto.

Após termos criado uma objeto baseado na classe ClasseEx1 podemos acessar os seus membros public. Para acessar um membro utilizamos a seguinte sintaxe:

nome_da_classe.nome_do_membro

No trecho de código a seguir alteramos o valor do campo contador e do campo teste, do objeto minhaclasse:

minhaclasse.contador = 125;
minhaclasse.teste    =  "PRIMEIRA CLASSE COM O C#";

O restante do exemplo é apenas para exibição dos resultados.

Importante = Observe que não “destruímos” o objeto minhaclasse no final do programa. Este procedimento não é mais necessário, como era em versões anteriores do VB, Visual C++ e VBA. Agora quando a função Main( ) encerra a sua execução a referência ao objeto minhaclasse deixa de existir. Se a referência não foi gravada, a instância da classe estará a disposição do coletor de lixo (garbage collector) do .NET, o qual irá liberar os recursos ocupados pela classe, quando necessário.

Membros de uma classe.

A seguir apresentamos uma descrição dos elementos que podem ser criados em uma classe, isto é, dos possíveis membros de uma classe.

Campos (fields)

Um campo é um membro do tipo variável utilizado para armazenar um determinado valor. No exemplo da Listagem 4.3 criamos dois campos: contador e teste. Os campos são os dados do objeto e podem determinar, juntamente com as propriedades, o estado do objeto em um determinado instante. Para cada membro de uma classe podemos aplicar modificadores, os quais descrevem a maneira como um determinado membro pode ser utilizado. Por exemplo, se queremos que um campo possa ser acessado fora da classe, precisamos utilizar o modificador public antes da definição do campo, como fizemos no exemplo da Listagem 4.3. Se quisermos que o campo somente seja acessado de dentro da classe podemos utilizar o modificador private. Outros modificadores para campos são: static, readonly e const. Falaremos sobre estes modificadores mais adiante.

Métodos (methods)

Um método contém código que atuo sobre os dados do objeto. Os métodos, falando em termos de orientação a objetos, descrevem as ações que podem ser realizadas pela classe. Na prática, a funcionalidade de uma classe é implementada através dos seus métodos.

Propriedades (properties)

As propriedades são um pouco diferente dos campos, pois para definir e ler o valor de uma propriedade são definidos métodos específicos. Get para obter o valor da propriedade e Set para definir o valor da propriedade. Veremos como criar e utilizar propriedades ainda neste capítulo.

Constantes (constants)

Uma constante é um campo cujo valor não pode ser alterado. Aprenderemos a criar constantes ainda neste capítulo.

Indexadores (indexers)

Esta é uma novidade do .NET. Um indexador é um array. O indexador permite que, facilmente, possamos indexar um objeto para facilitar a definição e obtenção dos valores da classe.

Eventos (events)

Um evento, normalmente, corresponde a uma ação do usuário, ação esta que é detectada pela classe e dispara a execução de algum código em resposta ao evento. É o conceito de evento que todos nós já conhecemos. Por exemplo, ao clicar em um botão de comando é disparado o evento Ao Clicar.

Agora aprenderemos a criar os diversos membros de uma classe.  Mas antes vamos falar um pouco sobre Construtores (Constructs) e Destrutores (Destructors).

Construtores e Destrutores de uma classe.

Ao criarmos uma classe podemos definir um método que será executado toda vez que uma instância da classe for criada. Este método especial é chamado de Construtor (Constructor) da classe. Colocamos neste método todo o código que deve ser executado na criação da classe. Por exemplo, se estamos criando uma classe que possuí métodos para fazer pesquisas em um banco de dados do SQL Server 2000. No método Construtor podemos incluir o código que estabelece a conexão com o banco de dados. Para que a classe seja de uso genérico, podemos definir parâmetros a serem passados para o método Construtor, de tal forma que a conexão seja estabelecida de acordo com o valor dos parâmetros passados para o método construtor. Se não definirmos um método construtor explicitamente, o Framework .NET define um método construtor sem parâmetros. No nosso exemplo anterior utilizamos o seguinte comando para criar uma instância da classe ClasseEx1 para o objeto minhaclasse:

ClasseEx1 minhaclasse = new ClasseEx1();  

O método construtor criado por padrão possui o mesmo nome da classe e não possui parâmetros – ClasseEx1( ). Se tivéssemos definido um método construtor com parâmetros, os mesmos teriam que ser passados no momento da criação do objeto. Por exemplo, se o método construtor deve receber um parâmetro inteiro, a criação do objeto minhaclasse ficaria assim:

ClasseEx1 minhaclasse = new ClasseEx1(10); 

Observe que estamos passando um parâmetro (10) para o método construtor.

A principal vantagem de utilizarmos um método construtor personalizado é que podemos garantir que o objeto seja instanciado corretamente, através da execução do código necessário a instanciação do objeto, no método construtor do mesmo. Quando o usuário instancia um determinado objeto, o método construtor do mesmo é chamado e deve finalizar a sua execução sem erros, caso contrário o usuário não poderá utilizar o objeto. Este comportamento garante que o código de inicialização, contido no método construtor do objeto, seja executado, antes que os demais membros do objeto possam ser utilizados.

O método construtor deve ter o mesmo nome da classe. Para provar que o método construtor é sempre executado, vamos considerar o exemplo da Listagem 4.4.

Considere o exemplo da Listagem 4.4.

Listagem 4.4 – Utilizando o método construtor. – Ex4cap4.cs

using System;
class ClasseEx2
{
            //  Definição do construtor da classe.
            // Observe  que o nome do método construtor
            // deve ter  o mesmo nome da classe.
            public  ClasseEx2()
            {
                Console.WriteLine("**************************************");
               Console.WriteLine("EXECUTANDO OS  COMANDOS DO CONSTRUTOR !");
               Console.WriteLine("ESTES COMANDOS SERÃO  EXECUTADOS SEMPRE");
               Console.WriteLine("QUE UMA INSTÂNCIA DA  CLASSE FOR CRIADA");
               Console.WriteLine("**************************************");  
            }
            public int  contador = 0;
            public  string teste = " ";
}
class Ex3cap4
{
            // Exemplo  3 - Capítulo 4.
            // Criação  de uma classe com dois membros.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public  static void Main()
            {
                        //  Agora crio uma variável do tipo ClasseEx2.
                        //  Esta variável é uma instância da classe ClasseEx2.
                        //  A simples criação de um objeto da classe fará
                        //  com que o seu construtor seja disparado e os
                        //  comandos do construtor serão executados.
                        ClasseEx2  minhaclasse = new ClasseEx2();            
            }
}

Digite o exemplo da listagem 4.4 e salve o mesmo em um arquivo chamado ex4cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.4. Você obterá os resultados indicados na Figura 4.5.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.5 Executando o programa ex4cap4.exe.

No nosso exemplo, no programa principal simplesmente criamos um objeto do tipo ClasseEx2. Ao instanciarmos o objeto foi disparado o seu método construtor, o qual exibe algumas informações na tela.

Além de um método construtor podemos criar um método destrutor. O método destrutor pode ser chamado para executar alguns comandos quando a referência ao objeto deixar de existir, ou seja, os comandos do método destrutor são chamados quando do encerramento do objeto.

Para criar um método destrutor basta criar um método com o mesmo nome da classe, porém precedido de um til (~). Por exemplo, para criar um método destrutor para a classe ClasseEx2( ), criada no exemplo anterior, utilizamos a seguinte sintaxe:

~ClasseEx2()
{
            comando1;
            comando2;
            ...
            comandon;
}

Modificadores para os membros de uma classe.

Conforme descrito anteriormente existem modificadores que definem a visibilidade dos membros de uma classe. Por exemplo, o modificador public torna o membro acessível de fora da classe, já o modificador private torna o membro disponível somente dentro da própria classe. A seguir uma descrição dos principais modificadores.

  • public: Torna o membro acessível de fora da definição da classe.
  • protected: O membro não pode ser acessado fora da classe, porém o membro está disponível para outras classes derivadas da classe base.
  • private: O membro não pode ser acessado fora da classe, nem mesmo por outras classes derivadas da classe base.
  • internal: O membro somente é visível na unidade de código onde o mesmo está definido. É um meio-termo entre public e protected, uma vez que o membro pode ser acessado por todas as classes definidas na mesma unidade (público para as classes da mesma unidade), porém não pode ser acessado por classes definidas em outras unidades (protected para unidades definidas em outras unidades).

Adicionando funcionalidade a uma classe – métodos.

A funcionalidade de uma classe é definida através da criação de métodos. Um método pode receber parâmetros e retornar um determinado resultado. Vamos fazer um pequeno estudo dos tipos de parâmetros que podem ser definidos para um determinado método.

Podemos definir os seguintes tipos de parâmetros:

  • Parâmetros In: Este tipo de parâmetro é o mais conhecido. É utilizado para passarmos o valor de uma variável para o método. Um inconveniente deste tipo de parâmetro é que o método não pode alterar o valor da variável, uma vez que somente foi passado o valor da variável e não uma referência para a mesma. O parâmetro definido no método é inicializado com uma cópia do valor da variável passada como parâmetro na chamada do método.

Mais uma vez vamos fazer uso de um exemplo para entendermos a criação de métodos e a utilização de parâmetros in.

Considere o exemplo da Listagem 4.5.

Listagem 4.5 – Utilizando parâmetro do tipo in. – Ex5cap4.cs

using System;
public class ClasseEx3
{
            //  Definimos um método para calcular o cubo de
            // uma  variável passada como parâmetro para o método.
            public int  calcula_cubo(int valor)
            {
                        //  Crio uma variável local do tipo int.
                        //  Atribuo o valor do parâmetro valor para a
                        //  variável local                       
                        int  auxint;
                        auxint  = valor; 
                        //  Altero o valor do parâmetro recebido.
                        valor  = 6;
                        return  auxint*auxint*auxint;
            }
}
class Ex5cap4
{
            // Exemplo  5 - Capítulo 4.
            // Criação  de uma classe com um método 
            // que  calcula o cubo de um número inteiro.
            //  Parâmetros in.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public  static void Main()
            {
                        //  Agora crio uma variável do tipo ClasseEx3.
                        //  Esta variável é uma instância da classe ClasseEx3.
                        ClasseEx3  minhaclasse = new ClasseEx3();            
                        //  Defino uma variável do tipo int e chamo o método
                        //  calcula_cubo, da classe minhaclasse, passando o 
                        //  valor inteiro como parâmetro.
                        int  valor;
                        //  Solicito que o usuário digite um valor inteiro.
                        Console.Write("Digite  um número inteiro ->");
                        string  aux1 = Console.ReadLine();
                        valor  = Convert.ToInt32(aux1);
                        //  Exibição do resultado.
            Console.WriteLine("*****************************************");
            Console.WriteLine("O  NÚMERO DIGITADO FOI    ->  {0}",valor);
            Console.WriteLine("*****************************************");
            Console.WriteLine("ELEVADO  AO CUBO -> {0}",minhaclasse.calcula_cubo(valor)); 
            Console.WriteLine("*****************************************");
            Console.WriteLine("VALOR  ORIGINAL DA VARIÁVEL VALOR -> {0}",valor);

            Console.WriteLine("*****************************************");                     
            }
}

Digite o exemplo da listagem 4.5 e salve o mesmo em um arquivo chamado ex5cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.5. Você obterá os resultados indicados na Figura 4.6.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.6 Executando o programa ex5cap4.exe.

Temos muitos detalhes interessantes a serem comentados no código deste exemplo.

Vamos iniciar pela definição de um método para calcular o cubo de um número passado como parâmetro. Isso é feito pelo trecho de código a seguir:

            //  Definimos um método para calcular o cubo de
            // uma  variável passada como parâmetro para o método.
            public int  calcula_cubo(int valor)
            {
                        //  Crio uma variável local do tipo int.
                        //  Atribuo o valor do parâmetro valor para a
                        //  variável local.
                        int  auxint;
                        auxint  = valor; 
                        //  Altero o valor do parâmetro recebido.
                        valor  = 6;
                        return  auxint*auxint*auxint;
            }

O método recebe um parâmetro do tipo inteiro chamado valor. Como o parâmetro é passado por valor, o método recebe uma cópia do valor da variável e não uma referência para a mesma. Neste caso temos um parâmetro in. Dentro do método declaramos uma variável do tipo int chamada auxint. Atribuímos o valor recebido como parâmetro para a variável auxint, através do comando:

auxint = valor;

Em seguida modificamos o valor da variável recebida como parâmetro. Fizemos isso para provar que esta modificação não altera o valor da variável original, definida no programa principal. Este fato pode ser comprovado na Figura 4.6, onde a variável original continua com o valor digitado pelo usuário, ou seja, a alteração feita no método calcula_cubo não afetou a variável original. Este é o comportamento esperado, uma vez que o parâmetro foi passado por valor e não por referência.

A última linha do método faz o cálculo, retornando o valor passado (agora armazenado na variável auxint), elevado ao cubo.

No programa principal declaramos e instanciamos uma variável chamada minhaclasse, a qual é do tipo ClasseEx3. Isto é feito com a seguinte linha de código:

ClasseEx3 minhaclasse = new ClasseEx3();         

Uma vez criado um objeto do tipo ClasseEx3 temos acesso ao método calcula_cubo(valor), ou seja: minhaclasse.calcula_cubo(valor), o qual é utilizado na seguinte linha de código:

Console.WriteLine("ELEVADO AO CUBO ->  {0}",minhaclasse.calcula_cubo(valor)); 

Este é um exemplo simples mas que salienta a criação e utilização de um método público. Também comprovamos que as alterações feitas em um parâmetro passado por valor não afetam o valor da variável no programa principal.

  • Parâmetros ref: Quando utilizamos parâmetros do tipo ref, como o próprio nome sugere, é passada uma referência para o parâmetro e não somente o valor do mesmo. Na prática isto significa que, se o método alterar o valor do parâmetro, esta alteração terá efeito na variável original, no programa principal. Vamos utilizar o mesmo exemplo anterior, porém apenas modificando o tipo de parâmetro. Aí vamos conferir se o valor da variável original, no programa principal, foi modificado.

Considere o exemplo da Listagem 4.6.

Listagem 4.6 – Utilizando parâmetro do tipo ref. – Ex6cap4.cs

using System;
public class ClasseEx4
{
            //  Definimos um método para calcular o cubo de
            // uma  variável passada como parâmetro para o método.
            public int  calcula_cubo(ref int valor)
            {
                        //  Crio uma variável local do tipo int.
                        //  Atribuo o valor do parâmetro valor para a
                        //  variável local.
                        int  auxint;
                        auxint  = valor; 
                        //  Altero o valor do parâmetro recebido.
                        valor  = 6;
                        return  auxint*auxint*auxint;
            }
}
class Ex6cap4
{
            // Exemplo  6 - Capítulo 4.
            // Criação  de uma classe com um método 
            // que  calcula o cubo de um número inteiro.
            //  Parâmetros ref.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public  static void Main()
            {
                        //  Agora crio uma variável do tipo ClasseEx4.
                        //  Esta variável é uma instância da classe ClasseEx4.
                        ClasseEx4  minhaclasse = new ClasseEx4();            
                        //  Defino uma variável do tipo int e chamo o método
                        //  calcula_cubo, da classe minhaclasse, passando o 
                        //  valor inteiro como parâmetro.
                        int  valor;
                        //  Solicito que o usuário digite um valor inteiro.
                        Console.Write("Digite  um número inteiro ->");
                        string  aux1 = Console.ReadLine();
                        valor  = Convert.ToInt32(aux1);
                        //  Exibição do resultado.
Console.WriteLine("*****************************************");
Console.WriteLine("O NÚMERO DIGITADO FOI    -> {0}",valor);
Console.WriteLine("*****************************************");
Console.WriteLine("ELEVADO AO CUBO ->  {0}",minhaclasse.calcula_cubo(ref valor)); 
Console.WriteLine("*****************************************");
Console.WriteLine("VALOR ORIGINAL DA VARIÁVEL VALOR  -> {0}",valor);
Console.WriteLine("*****************************************");                     
            }

}

Digite o exemplo da listagem 4.6 e salve o mesmo em um arquivo chamado ex6cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.6. Você obterá os resultados indicados na Figura 4.7.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.7 Executando o programa ex6cap4.exe.

Vamos comentar as diferenças em relação ao exemplo anterior.

Em primeiro lugar, na definição do método calcula_cubo, utilizamos a palavra ref para definir que o parâmetro será passado por referência, conforme indicado no trecho a seguir:

            public int  calcula_cubo(ref int valor)
            {
                        //  Crio uma variável local do tipo int.
                        //  Atribuo o valor do parâmetro valor para a
                        //  variável local.
                        int  auxint;
                        auxint  = valor; 
                        //  Altero o valor do parâmetro recebido.
                        valor  = 6;
                        return  auxint*auxint*auxint;
            }

Neste caso, como o parâmetro está sendo passado por referência, a alteração feita no parâmetro valor terá reflexos na variável valor no programa principal, o que pode ser comprovado pelos resultados exibidos na Figura 4.7.

Quando passamos um parâmetro por referência, na verdade estamos passando o endereço da variável. Por isso quando o método altera o valor da variável passada como parâmetro está, na prática, alterando o valor da variável original.

Também é importante salientar que no momento de utilizarmos o método, a palavra ref deve ser colocada antes do parâmetro que está sendo passado, conforme indicado na linha de código a seguir:

Console.WriteLine("ELEVADO AO CUBO ->  {0}",minhaclasse.calcula_cubo(ref valor)); 
  • Parâmetros out: Um parâmetro do tipo out é utilizado para que o método possa passar um resultado de volta para o programa que fez a chamado ao método. O programa que está chamando o método não precisa inicializar a variável que será retornada.

Vamos modificar o exemplo anterior para introduzirmos um parâmetro do tipo out.

Considere o exemplo da Listagem 4.7.

Listagem 4.7 – Utilizando parâmetro do tipo out. – Ex7cap4.cs

using System;
public class ClasseEx4
{
            //  Definimos um método para calcular o cubo de
            // uma  variável passada como parâmetro para o método.
            public void  calcula_cubo(int valor, out int valoraocubo)
            {
                        valoraocubo  = valor*valor*valor;
            }
}
class Ex7cap4
{
            // Exemplo  7 - Capítulo 4.
            // Criação  de uma classe com um método 
            // que  calcula o cubo de um número inteiro.
            //  Parâmetros out.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public static  void Main()
            {
                        //  Agora crio uma variável do tipo ClasseEx4.
                        //  Esta variável é uma instância da classe ClasseEx4.
                        ClasseEx4  minhaclasse = new ClasseEx4();            
                        //  Defino uma variável do tipo int e chamo o método
                        //  calcula_cubo, da classe minhaclasse, passando o 
                        //  valor inteiro como parâmetro.
                        int  valor;
                        int  valoraocubo;
                        //  Solicito que o usuário digite um valor inteiro.
                        Console.Write("Digite  um número inteiro ->");
                        string  aux1 = Console.ReadLine();
                        valor  = Convert.ToInt32(aux1);
                        //  Chamada do método calcula_cubo.
                        //  Após a execução do método o valor elevado
                        //  ao cubo está disponível na variável valoraocubo
                        //  a qual foi retornada pelo método.
                        minhaclasse.calcula_cubo(valor,out  valoraocubo);
                        //  Exibição do resultado.
            Console.WriteLine("*****************************************");
            Console.WriteLine("O  NÚMERO DIGITADO FOI    ->  {0}",valor);
            Console.WriteLine("*****************************************");
            Console.WriteLine("ELEVADO  AO CUBO -> {0}",valoraocubo); 
            Console.WriteLine("*****************************************");
            Console.WriteLine("VALOR  ORIGINAL DA VARIÁVEL VALOR -> {0}",valor);
            Console.WriteLine("*****************************************");                     
            }
}

Digite o exemplo da listagem 4.7 e salve o mesmo em um arquivo chamado ex7cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.7. Você obterá os resultados indicados na Figura 4.8.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.8 Executando o programa ex7cap4.exe.

Novamente mudamos o método calcula_cubo. Agora o método recebe um parâmetro inteiro por valore e retorna o cubo deste parâmetro através do parâmetro valoraocubo. O parâmetro valoraocubo é definido como um parâmetro de retorno ou saída (out), pelo uso da palavra out. O valor que deve ser retornado é atribuído ao parâmetro valoraocubo pelo código do método, conforme indicado no fragmento de código a seguir:

            public void  calcula_cubo(int valor, out int valoraocubo)
            {
                        valoraocubo  = valor*valor*valor;
            }

Também é importante salientar a utilização da palavra void antes do nome do método. O void informa que não será retornado nenhum valor pelo próprio método. O valor será retornado através da utilização de um parâmetro do tipo out.

A utilização do método calcula_cubo, no programa principal também é diferente dos exemplos anteriores. Neste exemplo primeiro declaramos uma variável do tipo int:

int valoraocubo;

Esta variável receberá o valor retornado pelo método calcula_cubo. Em seguida fazemos uma chamada ao método calcula_cubo, passando como primeiro parâmetro o valor digitado pelo usuário e o segundo parâmetro é o nome da variável que receberá o valor de retorno, conforme indicado no código a seguir:

minhaclasse.calcula_cubo(valor,out valoraocubo);

O restante do programa é simplesmente a exibição dos resultados obtidos.

O Polimorfismo posto em prática – Override.

Pelo princípio do Polimorfismo em uma classe derivada podemos sobrescrever (override), isto é, redefinir um ou mais métodos da classe base, desde que ao criar a classe básica o método tenha sido definido com permissão para ser redefinido. Para criar um método e permitir que o mesmo seja redefinido em uma classe derivada, utilizamos a palavra virtual. Considere o exemplo de definição a seguir:

virtual void metodo_que_pode_ser_redefinido(parâmetros)

Na classe derivada, para redefinirmos o método utilizamos a palavra override:

override void metodo_que_pode_ser_redefinido(parâmetros)

Para vermos o princípio do polimorfismo em ação vamos a um exemplo prático. Criaremos uma classe chamada Funcionários, na qual definimos um método chamado calcula_salario. Depois criaremos uma classe baseada na classe Funcionários, a qual faz um override do método calcula_salário.

Considere o exemplo da Listagem 4.8.

Listagem 4.8 – Fazendo o override de métodos no C#. – Ex8cap4.cs

using System;
public class ClasseFuncionarios
{
            //  Definimos um método para calcular o salário
            // com base  no cargo que foi passado como parâmetro.
            public  virtual int calcula_salario(string cargo)
            {
                        switch  (cargo)
                           {
                                   case  "gerente":
                                      return 2500;
                                   case  "diretor":
                                      return 4500;
                                   case  "funcionario":
                                      return 1500;
                                   default:
                                      return 1500;
                           }
            }
}
            // Agora  crio uma classe derivada de ClasseFuncionarios
            // chamada  HerdaDeFuncionarios.
            // Nesta  nova classe redefino o método calcula_salario
public class HerdaDeFuncionarios:ClasseFuncionarios
{
            // Vamos  redefinir o método para calcular o salário
            public  override int calcula_salario(string cargo)
            {
                        switch  (cargo)
                           {
                                   case  "gerente":
                                      return 3000;
                                   case  "diretor":
                                      return 4000;
                                   case  "funcionario":
                                      return 2000;
                                   default:
                                      return 1000;
                           }
            }
}
            // Agora  vamos definir o programa principal, onde
            //  utilizaremos o método que foi redefinido.
class Ex8cap4
{
            // Exemplo  8 - Capítulo 4.
            // Exemplo  de override de método.
            // Por:  Júlio Battisti
            // MCP,  MCP+I, MCSE, MCSE+I, MCSE, MCDBA
            public  static void Main()
            {
                        //  Crio um objeto FuncionarioOriginal baseado na classe
                        //  ClasseFuncionarios.
                        ClasseFuncionarios  FuncionarioOriginal = new ClasseFuncionarios();                  
                        //  Chamo o método originalmente definido na classe 
                        //  Passando como parâmetro "gerente"
                        String  aux1 = "gerente";
Console.WriteLine("********************************************");
Console.WriteLine("RESULTADOS DO MÉTODO  ORIGINAL");
Console.WriteLine("VALOR DO SALÁRIO PARA {0}, É ->  {1}",aux1,FuncionarioOriginal.calcula_salario(aux1));
                        //  Crio um objeto FuncionarioModificado baseado na classe
                        //  HerdaFuncionarios.
                        HerdaDeFuncionarios  FuncionarioModificado = new HerdaDeFuncionarios();   
                        //  Chamo o método que foi sobrescrito na classe HerdaDeFuncionarios
                        //  Passando como parâmetro "gerente"
                        String  aux2 = "gerente";
Console.WriteLine("********************************************");
Console.WriteLine("RESULTADOS DO MÉTODO  REDEFINIDO");
Console.WriteLine("VALOR DO SALÁRIO PARA {0}, É ->  {1}",aux1,FuncionarioModificado.calcula_salario(aux2));
            }
}

Importante= Alguns comandos aparecem divididos em duas linhas, por questão de espaço para exibição. Estes comandos devem ser digitados em uma única linha. A seguir temos um exemplo de um comando que está dividido em duas linhas por questões de espaço:

Console.WriteLine("VALOR DO SALÁRIO PARA {0}, É ->  {1}",aux1,FuncionarioModificado.calcula_salario(aux2));

Digite o exemplo da listagem 4.8 e salve o mesmo em um arquivo chamado ex8cap4.cs, na pasta C:\ExCsharp\cap4. Compile e execute o exemplo da listagem 4.8. Você obterá os resultados indicados na Figura 4.9.

Curso Completo de ASP.NET - Júlio Battisti
Figura 4.9 Executando o programa ex8cap4.exe.

Vamos analisar o código da Listagem 4.8.

Inicialmente criamos uma classe ClasseFuncionarios, na qual criamos um método chamado calcula_salario. Este método recebe um parâmetro do tipo string e retorna o valor do salário correspondente ao cargo passado como parâmetro para o método. Utilizamos a palavra virtual para informar que este método pode ser redefinido (override) em classes derivadas.

Em seguida criamos uma classe chamada HerdaDeFuncionarios. Esta classe é baseada na classe Classefuncionarios. Observe que para definir uma classe como senda baseada em outra utilizamos a sintaxe indicada a seguir:

public class HerdaDeFuncionarios:ClasseFuncionarios

simplesmente colocamos dois pontos (:) após o nome da classe e o nome da classe base.

Dentro da classe HerdaDeFuncionarios utilizamos a palavra override para redefinir o método calcula_salario, conforme indicado no trecho de código a seguir:

public class HerdaDeFuncionarios:ClasseFuncionarios
{
            // Vamos  redefinir o método para calcular o salário
            public  override int calcula_salario(string cargo)
            {                      
                        switch  (cargo)
                           {
                                   case  "gerente":
                                      return 3000;
                                   case  "diretor":
                                      return 4000;
                                   case  "funcionario":
                                      return 2000;
                                   default:
                                      return 1000;
                           }
            }
}

No programa principal criamos dois objetos. Um do tipo ClasseFuncionarios e um do tipo HerdaDeFuncionarios. Dentro da função Main chamamos o método calcula_salario das duas classes e comprovamos que realmente eles retornam valores diferentes para o cargo de gerente. Isto comprova que o método calcula_salario foi redefinido na classe herdada HerdaDeFuncionarios.

  « Lição anterior Δ Página principal ¤ Capítulos Próxima lição »
Quer receber novidades e e-books gratuitos?

 
 

Contato: Telefone: (51) 3717-3796 | E-mail: webmaster@juliobattisti.com.br | Whatsapp: (51) 99627-3434

Júlio Battisti Livros e Cursos Ltda | CNPJ: 08.916.484/0001-25 | Rua Vereador Ivo Cláudio Weigel, 537 - Universitário, Santa Cruz do Sul/RS, CEP: 96816-208

Todos os direitos reservados, Júlio Battisti 2001-2024 ®

LIVRO: MACROS E PROGRAMAÇÃO VBA NO EXCEL 2016 - CURSO COMPLETO E PRÁTICO

DOMINE A PROGRAMAÇÃO VBA NO EXCEL - 878 PÁGINAS - CLIQUE AQUI