C# - Classes Abstratas (revisão)


Eu já publiquei diversos artigos sobre os principais fundamentos da programação orientada a objetos nesses últimos anos, e, embora esses conceitos não sejam específicos de uma determinada linguagem, a sua implementação é. Como o meu foco inicial é o Visual Basic eu sempre abordei a implementação feita nesta linguagem.

Dessa forma eu estou revisando esses conceitos em novos artigos agora focando a implementação para a linguagem C#.

Classes Abstratas

O conceito de generalização na POO(Programação Orientada a Objetos) significa que um objeto encapsula comportamentos e estados para uma categoria de objetos.

Para ilustrar vamos pensar em algumas figuras geométricas conforme mostra a figura abaixo:

O objeto genérico neste exemplo é figura geométrica que iremos definir como uma classe abstrata.

Muitas formas geométricas possuem área, perímetro e cor.

O conceito de especificação na POO significa que um objeto pode herdar o comportamento e o estado comum de um objeto genérico, porém cada objeto precisa definir seu próprio estado e comportamento.

No exemplo cada forma geométrica tem sua fórmula particular para calcular a área e o perímetro.

A herança permite a reutilização de código.

Para o exemplo como sabemos que todas as formas possuem cor deveríamos definir um atributo cor em cada forma. Correto ?

Não. Incorreto.

Seria melhor criar uma classe com um atributo cor e fazer com que as demais formas especializadas herdassem esse atributo cor.

Neste caso podemos definir um classe base Forma como uma classe abstrata e uma classe derivada para cada forma especifica que desejamos tratar.

Na vida real nós nunca calculamos a área e o perímetro de uma figura geométrica; para fazer isso você precisa saber qual o tipo de figura geométrica (quadrado, triângulo, círculo, etc.) para implementar o cálculo usando a fórmula apropriada.

Para calcular a área podemos definir métodos abstratos na classe abstrata e dessa forma obrigar as classes que herdam da classe abstrata a implementar esses métodos. Com isso teremos certeza de que esses métodos foram implementados.

Definindo então os métodos CalcularArea() e CalcularPerimetro() como abstratos e assim estamos forçando as classes que derivam da classe base Forma, que também é abstrata, a definir o comportamento dos métodos implementando-os.

Agora que eu apresentei o cenário vamos definir os conceitos relacionados a classes abstratas e métodos abstratos

Classes Abstratas:

- Uma classe abstrata é uma classe que não pode ser instanciada. Você não pode criar um objeto a partir de uma classe abstrata.
- Uma classe abstrata
pode ser herdada e geralmente serve como classe base para outras classes.
- Uma classe abstrata pode conter métodos abstratos e métodos comuns. Uma classe abstrata também podem possuir construtores, propriedades, indexadores e eventos.
- Uma classe abstrata não pode ser estática (
static). Uma classe abstrata não pode ser selada (sealed).
- Uma classe abstrata pode herdar de outra classe abstrata.

Métodos Abstratos:

- Um método abstrato é um método que não possui implementação na classe abstrata. Um método abstrato possui somente a definição de sua assinatura. A sua implementação deve ser feita na classe derivada.
- Um método abstrato é um método
virtual e deve ser implementado usando o modificador override.
- Um método abstrato somente pode existir em uma classe abstrata.
- Um método abstrato não pode usar os modificadores
static e virtual.

Agora vamos a um exemplo de definição de classe e métodos abstratos.

Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo Console Application com o nome Classes_Abstratas;

Vamos definir no arquivo Programa.cs a classe abstrata Forma com o código a seguir:

     public abstract class Forma
    {
        private double _area;
        private string _cor;
        private double _perimetro;

        public string Cor
        {
            get
            {
                return _cor;
            }
            set
            {
                _cor = value;
            }
        }

        public double Area
        {
            get
            {return _area;}
            set
            {_area = value;}

        }
       
        public double Perimetro
        {
            get
            {return _perimetro;}
            set
            { _perimetro = value; }
        }

     
  public abstract void CalcularArea();
     
  public abstract void CalcularPerimetro();
        public string Descricao()
        {
            return "Sou a classe abstrata Forma.";
        }
    }
Na classe abstrata Forma temos definidos:

As propriedades públicas : Cor, Area e Perimetro

Os métodos abstratos : CalcularArea() e CalcularPermitero()

O método público Descricao()

 

A classe Forma não pode ser instanciada.

Se você tentar criar um objeto do tipo Forma :

Forma f = new Forma()

o compilador vai emitir a mensagem de erro:
Cannot create an instance of the abstract class or interface

Vamos criar a classe Quadrado que vai herdar da classe Forma
e implementar os métodos
CalcularArea() e CalcularPerimetro()

Observe que os métodos CalcularArea() e CalcularPerimetro() tiveram
apenas a declaração de sua assinatura e não foram implementados na
classe abstrata Forma.

Vamos definir a classe Quadrado que vai herdar da classe Figura digitando o código abaixo:

    public class Quadrado : Forma
    {
        private double lado;
        public double Lado
        {
            get
            {return lado;}
            set
            {lado = value;}
        }

        public override void CalcularArea()
        {
            this.Area = lado * lado;
        }

        public override void CalcularPerimetro()
        {
            this.Perimetro = 4 * lado;
        }
    }
A classe Quadrado possui a propriedade pública Lado

A classe Quadrado implementa usando o modificador
override os métodos CalcularArea() e CalcularPerimetro()

 

Observe que utilizamos o modificador override para implementar
os métodos abstratos

Vamos agora criar uma instância da classe Quadrado(), atribuir um valor ao seu lado e calcular a área e o perímetro incluindo o código abaixo no método Main():

 class Program
    {
        static void Main(string[] args)
        {
            Quadrado q = new Quadrado();
            Console.WriteLine(q.Descricao());
            Console.WriteLine("Informe o valor do lado do quadrado em metros.");
            q.Lado = Convert.ToInt32(Console.ReadLine());
            q.CalcularArea();
            q.CalcularPerimetro();

            Console.WriteLine("A área do quadrado é : " + q.Area + " m2 ");
            Console.WriteLine("O perímetro do quadrado é : " + q.Perimetro + " m ");
            Console.ReadKey();
        }
    }

No código acima temos :

- A criação de uma instância da classe Quadrado() : Quadrado q = new Quadrado();
- A utilização do método Descricao() :
Console.WriteLine(q.Descricao());
- A atribuição do valor do lado do quadrado à propriedade Lado:
q.Lado = Convert.ToInt32(Console.ReadLine());
- O cálculo da área e do perímetro:
q.CalcularArea(); e q.CalcularPerimetro();
- A exibição do resultado. (Veja a figura ao lado do código)

Então resumindo temos que:( http://pt.wikipedia.org/wiki/)

E estamos conversados...

Pegue o projeto completo aqui: Classes_Abstratas.zip

Rom 8:3 Porquanto o que era impossível à lei, visto que se achava fraca pela carne, Deus enviando o seu próprio Filho em semelhança da carne do pecado, e por causa do pecado, na carne condenou o pecado.
Rom 8:4
para que a justa exigência da lei se cumprisse em nós, que não andamos segundo a carne, mas segundo o Espírito.

Rom 8:5
Pois os que são segundo a carne inclinam-se para as coisas da carne; mas os que são segundo o Espírito para as coisas do Espírito.

Referências:


José Carlos Macoratti