Você está na página 1de 5

O que uma Classe Abstrata?

Outro dia um amigo me perguntou o que uma classe abstrata, eu sabia o que era,
mas travei na hora de explicar, acho que por estar nervoso acabei embromando, no final
at eu fiquei confuso sobre o que tinha falado. Por isso decidi que precisava fazer um
post sobre isso pra tentar esclarecer melhor esse assunto.

Conceito
Algumas pessoas acham que algo complexo, mas podemos tornar esse conceito
bem simples, ao nvel de ser compreendido por meros mortais...rsrs. Eu diria que a
abstrao algo artstico e que pode ser concebida e traduzida de diferentes formas e
por pessoas diferentes.

Mas vamos ao que interessa.

Abstrao quando voc tenta extrair de um objeto do mundo real tudo aquilo que
essencial para sua definio, mantendo as caractersticas mais relevantes e deixando
as irrelevantes de lado, tornando assim o objeto generalizado, podendo ser utilizado
em vrios aspectos do seu programa.

Podemos chamar as classes abstratas de Superclasses, elas funcionam como um


template, fornecendo s o que comum a todas as suas classes derivadas, possuem
mtodos com implementao incompleta deixando para cada uma de suas classes a
responsabilidade de implementar esses mtodos. Elas tambm no podem ser
instanciadas diretamente, voc precisa instanciar uma dessas classes herdadas.
Vejamos.

Aplicando
Como no exemplo abaixo, podemos ver uma classe abstrata (Veiculo) desenhada em
C#.
Leia os comentrios nas classes para entender melhor:

public abstract class Veiculo


{
//propriedades comum a todos os tipos de veculos.
protected int Rodas;
private bool Ligado { get; set; }

//construtor s pode ser acessado


//pelas classes que herdaro de Veiculo
protected Veiculo(int rodas)
{
Rodas = rodas;
}

//mtodos que sero implementados obrigatoriamente


//pelas classes que herdaro de Veiculo
public abstract void Ligar();
public abstract void Desligar();

//mtodos protegidos que s podem ser acessados


//pelas classes que herdaro de Veiculo
protected void SetLigar()
{
this.Ligado = true;
}

protected void SetDesligar()


{
this.Ligado = false;
}

//mtodos pblicos que podem ser acessados


//por uma instncia de Veiculo
public bool IsLigado()
{
return Ligado;
}

public int GetRodas()


{
return this.Rodas;
}
}

Agora vamos implementar a classe (Carro) que herdar de (Veiculo) e que ficar da
seguinte forma:

//aqui ns indicamos a herana, usando o dois ponto, ':'.


public class Carro : Veiculo
{
//definimos o valor para a propiedade Roda que definida
//especificamente por cada tipo de Veiculo
private static int _rodas = 4;

//a prop. Cinto criada somente para o tipo Carro.


private bool Cinto { get; set; }

//agora passamos a quantidade de Rodas para a classe


//Veiculo que implementa essa propriedade.
public Carro() : base(_rodas)
{
}
//implementando o mtodo obrigatrio que foi assinado na classe Veiculo,
//esse mtodo comum a todos os tipos de veiculos.
public override void Ligar()
{
//chamamos a class base (Veiculo) e usamos o mtodo
//de ligar que foi implementado na mesma.
base.SetLigar();

//indicamos que o Cinto est sendo usado ao ligar o carro.


this.Cinto = true;
}

//fazemos a mesma coisa com o mtodo Desligar,


//que tambm foi assinado na classe abstrata (Veiculo)
public override void Desligar()
{
base.SetDesligar();
this.Cinto = false;
}

//agora implementamos um mtodo especfico da classe (Carro).


//que indica se o Cinto est sendo usado ou no.
public bool UsandoCinto()
{
return this.Cinto;
}
}

Podemos fazer a mesma coisa para a classe Moto por exemplo:

public class Moto : Veiculo


{
private static int _rodas = 2;
private bool Capacete { get; set; }

public Moto() : base(_rodas)


{
}

public override void Ligar()


{
base.SetLigar();
this.Capacete = true;
}

public override void Desligar()


{
base.SetDesligar();
this.Capacete = false;
}

public bool UsandoCapacete()


{
return this.Capacete;
}
}

Mas note que agora passamos o valor de 2 Rodas para a classe (Veiculo) e ao invs
de Cinto a moto implementa uma propriedade especfica dela, que o Capacete.

Testando
Vejamos agora como fica o uso dessas classes usando Teste de Unidade.

[TestClass]
public class VeiculoTest
{
[TestMethod]
public void Veiculo_DeveLigarCarro()
{
//aqui ns temos uma intncia de Carro, porm do tipo Veiculo.
//dessa forma ns s teremos acesso as prop. e mtodos da superclasse
Veiculo.
Veiculo carro = new Carro();

//ligamos o carro.
carro.Ligar();

//e verificamos se o mesmo est ligado.


Assert.IsTrue(carro.IsLigado());
}

//fazemos a mesma coisa para desligar o carro.


[TestMethod]
public void Veiculo_DeveDesligarCarro()
{
Veiculo carro = new Carro();
carro.Desligar();

Assert.IsFalse(carro.IsLigado());
}

//aqui temos um teste que verifica se o carro tem mesmo 4 rodas.


[TestMethod]
public void Veiculo_DeveTer4RodasCarro()
{
Veiculo carro = new Carro();
var actual = carro.GetRodas();

const int expected = 4;

Assert.AreEqual(expected, actual);
}

//Agora ns testamos se ao ligar o carro o motorista est usando o Cinto.


[TestMethod]
public void Veiculo_DeveVerificarUsoDoCinto()
{
//repare que precisamos mudar o tipo da varivel, de Veiculo para Carro.
//assim podemos acessar o mtodo que s foi implementado na classe Carro.
Carro carro = new Carro();
carro.Ligar();

var actual = carro.UsandoCinto();

const bool expected = true;

Assert.AreEqual(expected, actual);
}
}

Legal n, agora voc j pode ter uma noo do que uma classe abstrata. Esse
conceito pode ser aplicado em outras situaes, por exemplo: Instrumentos como
abstrata e violo, teclado e bateria herdariam dessa classe, cada uma implementando
suas funes especficas e as que sejam comuns a elas.

Enfim, use sua criatividade e seja mais um artista.

Cdigo

Eu disponibilizei o cdigo usado acima no meu GitHub, baixa l e continua


implementando os testes que deixei em branco e cria outros novos, aproveita pra
treinar n.

Você também pode gostar