Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Sobre a chamada de membro estático em classe estática

Ficou confuso para mim o trecho em que o Guilherme tenta chamar um método abstrato dentro da classe abstrata. Eu entendi o que deve ser feito para corrigir o erro, mas não entendi o conceito por trás do erro e nem o conceito por trás da solução. Poderia me explicar melhor por favor?

Talvez o conceito de membro e classe estática também não esteja muito claro para mim.

Obrigado!

2 respostas

Bom dia, Rodolfo. Tudo bom?

Métodos abstratos só existem em classes abstratas. Como:

public abstract class Funcionario
{
    public abstract double GetBonificacao();
}

Como a classe Funcionario é abstrata, não podemos instanciar um objeto de seu tipo com Funcionario teste = new Funcionario(); por exemplo.

Mas, ainda podemos criar uma classe que derive de Funcionario, como:

public class Designer : Funcionario

E, como a classe base tem membros abstratos, a classe que Designer é obrigada a dar uma implementação:

public class Designer : Funcionario
{
    public override double GetBonificacao()
    {
        return 200;
    }
}

A palavra reservada override indica apenas ao compilador que o método GetBonificacao que escrevemos em Designer deve sobrescrever o método em Funcionario.

Neste exemplo, não é possível chamar a implementação do GetBonificacao da classe Funcionario a partir da classe Designer, afinal, este método nem tem implementação na classe base! Então, se escrevermos isto:

public override double GetBonificacao()
{
    return base.GetBonificacao() + 200;
}

Teremos um erro de compilação!

Para uma classe derivada sobrescrever um método da classe base é necessário que ele seja abstract, como vimos, ou virtual.

Se a classe Funcionario fosse:

public abstract class Funcionario
{
    public virtual double GetBonificacao()
    {
        return 100;
    }
}

Na classe derivada vamos conseguir sobrescrever esta implementação e chamar a implementação da classe base com base.GetBonificacao(), afinal, temos uma implementação na classe base.

Para reforçar, veja esse pequeno exemplo:

public abstract class Animal
{
    public abstract void FazerSom();
    public virtual void FazerSomVariasVezes()
    {
        FazerSom();
        FazerSom();
    }
}

public class Cachorro : Animal
{
    // A classe Cachorro é obrigada a
    // oferecer uma implementação ao método FazerSom
    // pq Cachorro não é abstrata e o método FazerSom()
    // da classe base é!
    public override void FazerSom()
    {
        Console.WriteLine("Wolf");
    }
}
public class Gato : Animal
{
    public override void FazerSom()
    {
        Console.WriteLine("Meow");
    }

    // A classe Gato não é obrigada a dar uma 
    // implementação ao FazerSomVariasVezes, mas
    // como é um método VIRTUAL, a classe derivada
    // pode sobrescrever!
    public override void FazerSomVariasVezes()
    {
        // Aqui podemos chamar a implementação na base,
        // porque o método VIRTUAL possui implementação!
        base.FazerSomVariasVezes();
        Console.WriteLine("Meooooow");
    }
}

E, no método Main:

Animal cao = new Cachorro();
Animal gato = new Gato();

cao.FazerSom();
gato.FazerSom();
solução!

A classe estática é aquela que não pode ser instanciada e não pode ser derivada nunca! Por exemplo:

public static class Calculadora
{
    public static class Fatorar(int numero)
    {
        // implementação
    }
}

Nunca poderemos criar uma instância de Calculadora. Se tentarmos executar o código new Calculadora() teremos um erro de compilação! O mesmo vale se tentarmos herdar este tipo public class CalculadoraCientifica : Calculadora { }

Por consequência, não faz sentido uma classe estática ter métodos abstract ou virtual, já que eles possuem relação com a herança.

Além disso, não faz sentido ter outros membros que não os estáticos, como um método:

public double Somar(double a, double b)
{
    return a + b;
}

Porque métodos não estáticos são chamados apenas através de instâncias! Mas, teremos uma contradição, porque classes estáticas nunca serão instanciadas.

Então, a única forma de usar uma classe estática é quando definimos apenas membros estáticos nela e usaremos Calculadora.Somar(1, 2) ou Calculadora.Fatorar(5) para chamar os métodos estáticos.

O que você acha? Ajudei com suas dúvidas?

Abs e bons estudos.