« Voltar
em c# oop

Construtores são herdados no C#?.

A resposta é não.

Mas vamos entender no que isso implica.
Vamos pegar como exemplo a classe Veiculo:

public class Veiculo  
{
    public string Modelo { get; set; }
    public int Ano { get; set; }
}

Agora, eu tenho a classe Carro que herda de Veiculo:

public class Carro : Veiculo  
{
    public int QuantidadeLugares { get; set; }
}

Desse jeito, para criar uma instância tanto de Carro quanto de Veiculo eu simplesmente faço um new:

Veiculo v = new Veiculo();  
Carro c = new Carro();  

Tranquilo, certo?

Agora, vamos supor que por alguma razão para o meu sistema, não faz sentido eu ter um Veiculo que não tenha Modelo ou Ano. Ou seja, quero obrigar o programador, sempre que for construir um Veiculo, a passar um modelo e ano.

Com faço isso?
Criando um construtor na classe Veiculo que receba esses dois parâmetros:

public class Veiculo  
{
    public string Modelo { get; set; }
    public int Ano { get; set; }

    public Veiculo(string Modelo, string Ano)
    {
       this.Modelo = Modelo;
       ths.Ano = Ano;
    }
}

Ok, agora vamos compilar...opa! Deu erro na classe filha, a Carro!

There is no argument given that corresponds to the required formal parameter 'Modelo' of 'Veiculo.Veiculo(string, int)'  

Mas pera...o que tá acontecendo aqui?
Vamos voltar um pouco.
Antes de criar o construtor que recebia os parâmetros, qual construtor eu tinha na minha classe Veiculo? O construtor padrão! Aquele sem argumentos que não recebe nada e não faz nada:

public class Veiculo  
{
    public string Modelo { get; set; }
    public int Ano { get; set; }

    public Veiculo()
    {
    }
}

E na classe filha também!
Mas tem um detalhe: sempre que inicializamos uma classe filha de outra no C#, ele precisa chamar um construtor para inicializar a classe base.
Ou seja, na classe filha o construtor padrão implícito faz uma chamada ao construtor da classe pai:

class Carro : Veiculo  
{
    public int QuantidadeAssentos { get; set; }

    public Carro() : base()
    {
    }
}

Repase no base na frente do construtor. Essa é uma chamada para o construtor da classe pai.
A partir do momento que fomos na classe pai e criamos um construtor, ele se torna o padrão da classe e portanto essa chamada ao construtor da classe pai na classe Veiculo não vai mais funcionar. Pois não existe mais um construtor sem argumentos lá.
Se quisermos que esse código funcione, temos que explicitamente criar o construtor padrão sem argumentos na classe Veiculo:

class Veiculo  
{
    public string Modelo { get; set; }
    public int Ano { get; set; }

    public Veiculo(string Modelo, int Ano)
    {
        this.Modelo = Modelo;
        this.Ano = Ano;
    }
    public Veiculo()
    {
    }
}

Legal, agora o erro foi embora!
Mas poxa...construtores não são herdados, portanto quando eu for construir um Carro eu não serei obrigado a passar o Modelo e Ano:

Carro c = new Carro("Fusca", 1969); // Erro de compilação!  

Sempre que eu precisar de um construtor na classe filha igual a um que eu tenho na classe pai, preciso declará-lo explicitamente:

class Carro : Veiculo  
{
    public int QuantidadeAssentos { get; set; }

    public Carro(string Modelo, int Ano)
    {
        this.Modelo = Modelo;
        this.Ano = Ano;
    }
}

Mas poxa, veja que esse construtor faz exatamente a mesma coisa que o construtor da classe pai.
Não seja por isso, podemos reaproveitar o comportamento do construtor da classe pai da seguinte forma:

class Carro : Veiculo  
{
    public int QuantidadeAssentos { get; set; }

    public Carro(string Modelo, int Ano) : base(Modelo, Ano) //chama o construtor da classe pai que tem os mesmos tipos de argumentos
    {

    }
}

Legal, né?


Quer ganhar 15% de desconto pra gastar na Casa do Código e ainda ficar em dia com as minhas postagens e outras promoções e sorteios legais? Assina minha newsletter: http://gabsferreira.com/newsletter/ (:

Se quiser, curta minha página no Face também! O endereço é https://www.facebook.com/devgabsferreira

comments powered by Disqus