Abstração e Interface (POO)

Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)

Esta imagem não tem muito a ver com informática.
mas gostei dela por se tratar de uma imagem abstrata.
Abstração e Interface

Abstração
Para entendermos o que é abstração e interface em programação, vamos entender primeiro o conceito.Abstração quer dizer que devemos considerar as qualidades e comportamentos independentes dos objetos a que pertencem, isolamos seus atributos considerando o que certo grupo de objetos têm em comum.

Vamos imaginar uma mesa, todos nós iremos imaginar uma mesa que tenha pés, uma base e uma finalidade. Mas não importa quantos pés, ou tipo de base ou a finalidade da mesa. Isso não fará com que a mesa que eu imaginei, deixe de ser uma mesa. Ela sempre será uma mesa.

Em programação iremos dizer ao computador para ser um objeto mesa. Mas antes disso precisamos dizer a este objeto qual seria a sua estrutura inicial. Neste caso teremos uma classe abstrata Mesa.

Classes abstratas como vocês já devem ter percebido servem como base para outras classes que queiram ser do mesmo grupo de objetos.

Uma classe abstrata não pode ser criada, quer dizer que não pode ser instanciada. Não podemos usar o new para criar um novo objeto de uma classe abstrata. Uma classe abstrata só pode ser herdada, e todo método, propriedade, evento que for abstrato deverá ser implementado pela classe filha.
Vamos declarar a nossa classe Mesa, que irá servir de base para as outras mesas.

namespace Desenvolvedores.Net.AbstracaoInterface
{
public enum TipoMesa
{
Redonda,
Quadrada,
Retangular
}

public enum TipoBase
{
Vidro,
Madeira,
Aluminio
}

/*
* aqui declaramos a nossa classe
* como abstrata
*/
public abstract class Mesa : IMesa
{

public Mesa()
{
Pes = 4;
}

/*
* reparem que as propriedades não são abstratas,
* não é obrigatório.
* Declare como asbtrato apenas o que você deseja
* que seja implementado nas classes filhas
*/
public TipoBase Base { get; set; }
public TipoMesa Tipo { get; set; }
public int Pes { get; set; }

/*
* aqui irei ter propriedades abstratas para servir de exemplo
*/
public abstract bool Quebrada { get; set; }
public abstract string Finalidade { get; }

/*
* Aqui teremos um método abstrato, onde a classe filha
* será obrigatória a implementar
*/
public abstract void Quebrar();

public virtual void Consertar()
{
Quebrada = false;
}

public override string ToString()
{
return "Olá. Eu sou uma mesa do tipo " +
Tipo.ToString() + " e minha base é de " +
Base.ToString() + ".\nEu tenho " + Pes.ToString() + " pés. " +
"E minha finalidade é " + Finalidade.Trim() + "\n" +
"*".PadLeft(80, '*');
}

}
}

Agora temos uma classe abstrata que será nossa base para todas as nossas mesas.

Antes de continuar, vamos falar sobre interfaces.

Interfaces
Interfaces são como as classes abstratas, mas nelas não podemos implementar nenhum método, apenas declarar suas assinaturas.
Uma classe ao herdar uma interface deverá escrever todos os seus métodos (iremos ver isso em Herança de Interface nos próximos artigos), ao contrário da classe abstrata que só iremos escrever os métodos abstratos.
Com o tempo você aprenderá a ver qual é mais útil dependendo da situação é mais vantajoso usar uma classe abstrata ou uma interface. Não existe uma regra para definir isso, mas sim a necessidade de uma ou de outra.

Por boas práticas, todas as interfaces começa com I, vamos declarar nossa interface IMesa.

namespace Desenvolvedores.Net.AbstracaoInterface
{
interface IMesa
{
TipoBase Base { get; set; }
string Finalidade { get; }
bool Quebrada { get; set; }
TipoMesa Tipo { get; set; }
int Pes { get; set; }

void Consertar();
void Quebrar();
}
}

Percebam que a nossa interface IMesa tem todos os métodos e propriedades para fazer de outra classe uma Mesa, e vejam também que eu não escrevi nenhum código nela, apenas declarei as assinaturas dos métodos e propriedades. 🙂

Exemplo de Uso
Agora como exemplo de uso iremos criar alguns tipos de mesas.
Crie uma aplicação console em C#.

Copie os códigos abaixo.

Uma mesa redonda. Estamos herdando aqui a classe abstrata Mesa.

namespace Desenvolvedores.Net.AbstracaoInterface
{
/*
* repare que ao herdarmos a classe
* abstrata Mesa. Só escrevemos os métodos e propriedades
* que foram definidos como abstrato na classe pai Mesa.
*/
public class MesaRedonda : Mesa
{
public override bool Quebrada { get; set; }
public override string Finalidade
{
get { return "para discutir futebol."; }
}

public override void Quebrar()
{
Quebrada = true;
}
}
}

Agora aqui uma mesa de jantar, que também herda a classe abstrata Mesa.

namespace Desenvolvedores.Net.AbstracaoInterface
{
/*
* repare que ao herdarmos a classe
* abstrata Mesa. Só escrevemos os métodos e propriedades
* que foram definidos como abstrato na classe pai Mesa.
*/
class MesaDeJantar : Mesa
{
public override bool Quebrada { get; set; }

public override string Finalidade
{
get { return "para jantares em família."; }
}

public override void Quebrar()
{
Quebrada = true;
}
}
}

Agora aqui uma mesa de escritório. Nela herdamos a interface, reparem que tive que desenvolver todo o código para a classe filha, a interface apenas trouxe a assinatura dos métodos.

namespace Desenvolvedores.Net.AbstracaoInterface
{
/*
* Nesta classe herdamos apenas a interface IMesa.
* Vejam que tive que escrever todo o código para a classe.
* A interface trouxe apenas as assinaturas dos métodos.
*(herança de interface)
* No caso de uma classe abstrata não há a necessidade
* de se fazer todos os métodos (herança de implementação)
*/
class MesaEscritorio : IMesa
{
public MesaEscritorio()
{
Pes = 4;
}

public TipoBase Base { get; set; }

public string Finalidade
{
get { return "para trabalhar."; }
}

public bool Quebrada { get; set; }

public TipoMesa Tipo { get; set; }

public int Pes { get; set; }

public void Consertar()
{
Quebrada = false;
}

public void Quebrar()
{
Quebrada = true;
}

public override string ToString()
{
return "Olá. Eu sou uma mesa do tipo " +
Tipo.ToString() + " e minha base é de " +
Base.ToString() + ".\nEu tenho " + Pes.ToString() + " pés. " +
"E minha finalidade é " + Finalidade.Trim() + "\n" +
"*".PadLeft(80, '*');
}
}
}

E finalmente. A aplicação de exemplo:

namespace Desenvolvedores.Net.AbstracaoInterface
{
class Program
{
static void Main(string[] args)
{
//aqui criamos os nossos objetos da forma tradicional
MesaRedonda mesaRedonda = new MesaRedonda();
mesaRedonda.Base = TipoBase.Madeira;
Console.WriteLine(mesaRedonda.ToString());

MesaDeJantar mesaJantar = new MesaDeJantar();
mesaJantar.Tipo = TipoMesa.Retangular;
Console.WriteLine(mesaJantar.ToString());

MesaEscritorio mesaEscritorio = new MesaEscritorio();
mesaEscritorio.Tipo = TipoMesa.Quadrada;
Console.WriteLine(mesaEscritorio.ToString());
Console.WriteLine("Usando a interface e a classe abstrata " +
"para criar novas mesas\n" + "*".PadLeft(80,'*'));

//aqui iremos usar um pouco de polimorfismo
//que iremos discutir tambem em nossos próximos artigos
//logo, não se preocupe em saber a definição
//apenas atente para o uso da interface e da classe abstrata
//como tipo de variável

//a minha mesa pode ser de escitório.
IMesa iMesa = new MesaEscritorio();
iMesa.Tipo = TipoMesa.Redonda;
iMesa.Base = TipoBase.Madeira;

Console.WriteLine(iMesa.ToString());

//de jantar
iMesa = new MesaDeJantar();
iMesa.Base = TipoBase.Aluminio;
Console.WriteLine(iMesa.ToString());

//ou redonda
iMesa = new MesaRedonda();
Console.WriteLine(iMesa.ToString());

//e alem da interface eu posso usar a própria classe
//abstrata para definir o meu tipo de mesa
Mesa mesa = new MesaDeJantar();
Console.WriteLine(mesa.ToString());

mesa = new MesaRedonda();
mesa.Tipo = TipoMesa.Quadrada;
mesa.Base = TipoBase.Vidro;
Console.WriteLine(mesa.ToString());

Console.ReadKey();
}
}
}

Bom. espero ter respondido às dúvidas sobre abstração.
Só para reforçar, é simples. Deixe nas classes abstratas ou interfaces, todos os métodos que serão comuns aos seus objetos do mesmo grupo. Assim sendo, sempre que você declarar uma variável de um tipo Interface ou classe Abstrata poderá criar qualquer tipo de objeto que implemente uma das duas.

Ver Índice

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

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

Você vai gostar de...

Postagens populares.

3 Comments

  1. Ótimo material, vou fazer referencia desta publicação aos interessados em POO.
    Ótimo trabalho.

  2. […] não conheçam Interface e Abstração leiam este […]

Deixe um comentário para Herança (POO) « Desenvolvedores.Net – TechBlog Cancelar resposta

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.