Desenvolvedores.Net - TechBlog

Tag Archives: polymorphism

Polimorfismo (POO)

10
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (8 votos, média: 3,50 de 5)
Loading...
12 de fevereiro de 2011
Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)
Iremos entrar agora em nosso último tópico sobre POO, e  muito interessante que é polimorfismo.Se você seguiu toda a trajetória do artigo sobre POO deve ter visto várias formas de polimorfismo (isso não foi um trocadilho) durante a leitura.

Vimos em:

Herança (POO)
Tipos Genéricos (Generics) (POO)
Abstração e Interface (POO)

Leia este artigo e depois do entendimento, volte a eles e tente identificar o uso do polimorfismo.

Aqui iremos abordar o polimorfismo de uma forma mais ampla e detalhada. Então vamos lá.

Polimorfismo

Etimologicamente, polimorfismo quer dizer:

1 Que se apresenta ou ocorre sob formas diversas.
2 Que assume ou passa por várias formas, fases etc.

Em orientação a objetos podemos dizer também que o objeto pode ter “vários comportamentos”.

Quando você chama um método ele pode se referir a qualquer objeto, por exemplo o método “Abrir()”, ele pode abrir uma tampa de garrafa, uma janela, uma porta, pode abrir alguma coisa.

Em polimorfismo é necessário que os métodos tenham a mesma assinatura, o mecanismo utilizado é o de redefinição de métodos (Overriding Definições – Intermediário (POO)) , não confundir com sobrecarga de métodos (Overload Definições – Intermediário (POO)).

Em polimorfismo podemos:

1 Instanciar objetos diferentes para um mesmo tipo.
2 Substituir condicionais com o polimorfismo.
3 Usar parâmetros que aceitam diferentes tipos de objetos desde que tenham a mesma herança de classes.

Vamos à alguns exemplos para reforçarmos as idéias.

Vamos criar nossas classes que servirão de base para todo o exemplo.

Iremos criar uma calculadora bem simples, que implemente as quatro operações básicas.

Classe Base

namespace Polimorfismo
{
    /// <summary>
    /// Classe base para efetuar os cálculos matemáticos
    /// </summary>
    abstract class CalculoMatematico
    {
        public virtual double Valor1 { get; set; }
        public virtual double Valor2 { get; set; }

        public abstract double Resultado();
    }
}

Multiplicação

namespace Polimorfismo
{
    class Multiplicacao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 * Valor2;
        }
    }
}

Divisão

namespace Polimorfismo
{
    class Divisao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 / Valor2;
        }
    }
}

Adição

namespace Polimorfismo
{
    class Adicao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 + Valor2;
        }
    }
}

Subtração

namespace Polimorfismo
{
    class Subtracao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 - Valor2;
        }
    }
}

Vamos agora ao primeiro exemplo.
Partindo de um mesmo tipo de objeto, podemos instanciar os outros tipos.
Mas para isso todos as classes devem implementar a mesma classe Pai.

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //veja que definimos o tipo
            //como CalculoMatematico
            CalculoMatematico calc;

            //aqui é criado como Adicao
            calc = new Adicao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Divisao
            calc = new Divisao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Subtracao
            calc = new Subtracao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Multiplicacao
            calc = new Multiplicacao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            Console.ReadKey();
        }
    }
}

O nosso segundo item diz que podemos substituir condicionais com o uso de polimorfismo.
Será?
Vamos ver os exemplos abaixo, reparem bem na diferença entre os dois métodos da classe Calculadora

Definição da classe Calculadora:

namespace Polimorfismo
{
    public enum TipoCalculo
    {
        Adicao,
        Subtracao,
        Multiplicacao,
        Divisao
    }

    static class Calculadora
    {
        /// <summary>
        /// Neste método temos que informar o tipo
        /// de calculo que o mesmo irá fazer
        /// </summary>
        /// <param name="tipo">tipo do calculo feito</param>
        /// <param name="valor1">valor 1 para o calculo </param>
        /// <param name="valor2">valor 2 para o calculo</param>
        /// <returns>resultado da expressão</returns>
        public static double Calcular(TipoCalculo tipo, double valor1, double valor2)
        {
            double resultado = 0;

            //e aqui temos o condicional switch
            switch (tipo)
            {
                case TipoCalculo.Adicao:
                    resultado = valor1 + valor2;
                    break;
                case TipoCalculo.Subtracao:
                    resultado = valor1 - valor2;
                    break;
                case TipoCalculo.Multiplicacao:
                    resultado = valor1 * valor2;
                    break;
                case TipoCalculo.Divisao:
                    resultado = valor1 / valor2;
                    break;
                default:
                    throw new NotImplementedException("nunca poderá chegar aqui");
            }

            return resultado;
        }

        /// <summary>
        /// fazendo deste modo não precisamos
        /// utilizar nenhum condicional
        /// </summary>
        /// <param name="calc">tipo de calculo</param>
        /// <returns>resultado do calculo</returns>
        public static double Calcular(CalculoMatematico calc)
        {
            return calc.Resultado();
        }
    }
}

Exemplificando…

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //aqui vamos usar o condicional
            Console.WriteLine("Usando o Condicional");
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Adicao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Divisao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Multiplicacao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Subtracao, 23, 34).ToString("N2"));

            Console.WriteLine("".PadLeft(80, '-'));
            Console.WriteLine("Usando polimorfismo");
            //Aqui nao iremos usar o condicional.
            //substituiremos pelo uso do polimorfismo
            CalculoMatematico calc;

            //aqui é criado como Adicao
            calc = new Adicao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Divisao
            calc = new Divisao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Multiplicacao
            calc = new Multiplicacao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Subtracao
            calc = new Subtracao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            Console.ReadKey();
        }
    }
}

Na classe Calculadora, além de exemplificarmos a substituição de um condicional com o uso do polimorfismo, ainda vimos a sobrecarga de métodos, temos dois métodos Calcular com assinaturas diferentes.

Para um melhor entendimento de sobrecarga recomendo a leitura do tópico Definições – Intermediário (POO).

E vimos também o item 3 que diz que podemos aceitar parâmetros de várias formas de objetos reparem que o método public static double Calcular(CalculoMatematico calc) aceitou os quatro tipos básicos.

Conclusão

Vimos o uso do polimorfismo em métodos, mas podemos usar a idéia em construtores, propriedades, no uso de Generics (Tipos Genéricos (Generics)), que podemos chamar de Polimorfismo Genérico.

Podemos citar rapidamente o uso de downcast (converter em uma classe mais específica) ,  upcast (definir em uma classe mais genérica).

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //definir objeto
            CalculoMatematico calc = new Adicao();
            calc.Valor1 = 22;
            calc.Valor2 = 33;

            //downcast (classe mais específica)
            Adicao adicao = (Adicao)calc;
            Console.WriteLine(adicao.Resultado());

            //upcast (classe mais genérica)
            calc = (CalculoMatematico)adicao;
            Console.WriteLine(calc.Resultado());

            Console.ReadKey();
        }
    }
}

Ver Índice

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Programação Orientada a Objetos (POO)

17
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (12 votos, média: 5,00 de 5)
Loading...
13 de dezembro de 2010
Olá Pessoal.Agora vou iniciar uma série de artigos sobre Programação Orientada a Objetos (POO) ou Object-Oriented Programming (OOP).Na medida do possível irei mostrar como programar cada explicação em alguma linguagem.Este primeiro artigo irá servir como um índice para os outros, sempre que eu postar um item deste índice, irei modificar este artigo fazendo um link daqui para a explicação e vice-versa.Então vamos lá, mãos à obra e vamos ver o que teremos 🙂
É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s