Arquivo da tag: Orientação a objetos

Definindo classes em C# – Parte 4

Herança

Herança é um tipo de relacionamento/associação entre classes. É usada quando é necessário que uma determinada classe tenha todas as características de outra classe com algumas modificações em seu comportamento, ou mesmo algumas funcionalidades adicionais.

As palavras generelização e especialização fazem parte do conceito de Herança. Uma classe “mais genérica” (generelização) pode gerar uma nova classe que herda suas características, mas permitindo modificações e novas implementações, ou seja, a nova classe é uma especialização da classe genérica.

Um exemplo tradicional usado para explicar o conceito de herança é a definição das classes Pessoa, PessoaFisica e PessoaJuridica. A classe Pessoa é genérica, e contém atributos, métodos e propriedades que podem representar qualquer pessoa. Já as classes PessoaFisica e PessoaJuridica respectivamente representam uma características para uma pessoa física e pessoa jurídica, e são classes especializadas, pois especializam a classe Pessoa.

Em C# uma relação de Herança é implementada com o uso do símbolo “:” (dois pontos) na definição da classe.

Classe genérica (Pessoa).

public class Pessoa
{
    int _id;
    DateTime _dataCadastro;

    public int Id
    {
        get { return this._id; }
        set { this._id = value; }
    }

    public DateTime DataCadastro
    {
        get { return _dataCadastro; }
        set { _dataCadastro = value; }
    }

    public int GerarId()
    {
        throw new NotImplementedException();
    }
}

Classes especializadas PessoaFisica e PessoaJuridica.

public class PessoaFisica: Pessoa
{
    string _nome;
    DateTime _dataNascimento;
    string _cpf;

    public string Nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    public DateTime DataNascimento
    {
        get { return _dataNascimento; }
        set { _dataNascimento = value; }
    }

    public PessoaFisica(int id, DateTime dataCadastro, string nome, string cpf)
    {
        base.Id = id;
        base.DataCadastro = dataCadastro;
        this._cpf = cpf;
        this._nome = nome;
    }

    public PessoaFisica EncontrarPorCpf(string cpf)
    {
        throw new NotImplementedException();
    }
}

public class PessoaJuridica : Pessoa
{
    string _cnpj;
    string _razaoSocial;

    public string Cnpj
    {
        get { return _cnpj; }
        set { _cnpj = value; }
    }

    public string RazaoSocial
    {
        get { return _razaoSocial; }
        set { _razaoSocial = value; }
    }

    public PessoaJuridica(int id, DateTime dataCadastro, string cnpj, string razaoSocial)
    {
        base.Id = id;
        base.DataCadastro = dataCadastro;
        this._cnpj = cnpj;
        this._razaoSocial = razaoSocial;
    }

    public PessoaJuridica EncontrarPorCnpj(string cnpj)
    {
        throw new NotImplementedException();
    }
}

Graficamente a Herança no Diagrama de Classe tem o seguinte aspecto.

Como é possível perceber no exemplo acima, as classes especializadas tem acesso aos membros implementados na classe genérica atráves da palavra reservada base.

Métodos Virtuais

A classe genérica pode oferecer métodos que podem ser reescritos nas classes especializadas. Isso é possível quando um método é decorado com a palavra reservada virtual. Para reescrevê-lo na classe especializada, o método deve ser decorado com a palavra reservada override.

public class Pessoa
{
    ...

    public virtual Pessoa EncontarPorId(int id)
    {
        throw new NotImplementedException();
    }
}

public class PessoaJuridica : Pessoa
{
    ...

    public override Pessoa EncontarPorId(int id)
    {
        //Nova implementação
    }
}

public class PessoaFisica : Pessoa
{
    ...

    public override Pessoa EncontarPorId(int id)
    {
        //Nova implementação
    }
}

Por enquanto é só isso. Até o próximo.