1
resposta

Interface ou Polimorfismo

Temos uma interface. As classes que implementam esse interface, por obrigação, tem que implementar o método.

public interface IAutenticavel
    {
        bool Autenticar(string senha);
    }
public abstract class FuncionarioAutenticavel : Funcionario, IAutenticavel
    {
        public string Senha { get; set; }

        //Construtor

        public bool Autenticar(string senha)
        {
            return Senha == senha;
        }
    }
public class ParceiroComercial : IAutenticavel
    {
        public string Senha { get; set; }
        public bool Autenticar(string senha)
        {
            return Senha == senha;
        }
    }

A Classe SistemaInterno receberá no parâmetro um objeto que é implementado por uma interface.

public class SistemaInterno
    {
        public bool Logar(IAutenticavel funcionario, string senha)
        {
            bool usuarioAutenticado = funcionario.Autenticar(senha);

            if(usuarioAutenticado)
            {
                Console.WriteLine("Bem-vindo ao sistema!");
                return true;
            }
            else
            {
                Console.WriteLine("Senha incorreta!");
                return false;
            }
        }
    }

Faria diferença na minha aplicação se eu tivesse vários métodos Logar só que com assinaturas diferentes? Exemplo:

public class SistemaInterno
    {
        public bool Logar(Funcionario funcionario, string senha)
        {
            bool usuarioAutenticado = funcionario.Autenticar(senha);

            if(usuarioAutenticado)
            {
                Console.WriteLine("Bem-vindo ao sistema!");
                return true;
            }
            else
            {
                Console.WriteLine("Senha incorreta!");
                return false;
            }
        }
    public bool Logar(ParceiroComercial parcom, string senha)
        {
            bool usuarioAutenticado = funcionario.Autenticar(senha);

            if(usuarioAutenticado)
            {
                Console.WriteLine("Bem-vindo ao sistema!");
                return true;
            }
            else
            {
                Console.WriteLine("Senha incorreta!");
                return false;
            }
        }
    }
1 resposta

O tipo mais genérico vai ser preferido quando não houver uma versão polimórfica mais especializada.

A vantagem do método que recebe qualquer objeto que implemente uma dada interface é a diminuição da repetição de código, mas se algum dos herdeiros da interface precisar de tratamentos mais específicos, é perfeitamente possível e permitida a implementação de um método polimórfico mais especializado.

Ex.:

public class SistemaInterno
{
    public bool Logar(IAutenticavel funcionario, string senha)
    {
        bool usuarioAutenticado = funcionario.Autenticar(senha);

        if(usuarioAutenticado)
        {
            Console.WriteLine("Bem-vindo ao sistema!");
            return true;
        }
        else
        {
            Console.WriteLine("Senha incorreta!");
            return false;
        }
    }

    public bool Logar(ParceiroComercial parcom, string senha)
    {
        // Podemos começar chamando o método genérico e continuando depois de sua execução, mas isso não é obrigatório.
        bool autenticacao = Logar(parcom as IAutenticavel, senha); // Com o cast aqui, chamamos o método mais genérico e guardamos o seu retorno
        // Depois disso podemos fazer os tratamentos específicos para parceiros comerciais, como  o exemplo abaixo
        if (autenticacao)
        {
            Console.WriteLine("Identificamos que o sr. é um de nossos preciosos parceiros comerciais, é sempre um prazer recebê-lo.");
        }
        return autenticacao; // Retornamos o valor que foi retornado pelo método "genérico".
    }
}