martes, 12 de mayo de 2015

Preguntas de Entrevista .NET - Diferencias entre Abstract Class e Interface

Esta pregunta es uno de los clásicos en las entrevistas para desarrollador .NET. Lo que quiero decir con esto es que no hay entrevista sin esta pregunta. Es muy importante que podamos enumerar claramente las diferencias entre ambos, explicar los conceptos que hay detrás de cada una de estas diferencias, conceptos teóricos y practico de la implementación. Y por ultimo que podamos emitir una opinion sobre cual utilizar en que momento y porque.

Qué es una Abstract Class ?


Lo primero que deberíamos hacer es explicar con claridad cual es el concepto de Abstract Class, estas son clases que brindan un contracto para que las clases que derivan de estas sigan. Lo que quiere esto decir es que en una clase abstracta vamos a definir un marco para las clases que de esta deriven, definiendo funcionalidad (la cual puede ser sobrescrita o definiendo contratos que deben ser implementados. Cabe destacar que de una clase abstracta no se puede crear una instancia con lo cual para acceder a su funcionalidad debemos derivar de esta en una clase no abstracta.
En principio existen dos formas de declarar funcionalidad en una clase abstracta como podemos ver en el código que esta a continuación.

    public abstract class Vehiculo
    {
        virtual public string Andar()
        {
            return "Estoy funcionando";
        }

        abstract public string Frenar();
    }

    public class Automovil : Vehiculo
    {
        public override string Frenar()
        {
            return "Acabo de frenar";
        }
    }

Como podemos ver declaramos en nuestra clase abstracta dos métodos, uno utilizando la palabra reservada virtual, con esto lo que hacemos es definir un método que tiene un comportamiento básico definido pero deja la puerta abierta a que la clase que deriva de esta puede sobre escribir este comportamiento. Y otro método que utiliza la palabra reservada abstract que como se puede ver no tiene comportamiento definido y con esto lo que hacemos es definir un contracto que debe ser implementado en la clase que deriva como se muestra en el ejemplo anterior. De esta manera salen a la luz dos de las formas en las que podemos utilizar una clase abstracta y es para definir comportamiento o para definir un contracto.
Existe algo que debe ser remarcado en este punto que las clases abstractas se rigen por las reglas de la herencia con lo cual una clase solo puede heredar de una clase abstracta (o no) y no mas de una clase.

Qué es una Interface?


Las interfaces son un recurso que nos brinda el framework para definir contratos que deben ser definidos por las clases que implementan dichas interfaces. Cabe destacar que una interface no define comportamiento, el mismo si o si debe ser definido en las clases que la implementan. Las clases que implementan una interface deben definir comportamiento para todos los miembros de la interface. Como las interfaces no son clases una clase puede implementar cuantas interfaces se desee como se puede ver en el ejemplo siguiente.

    public interface IDibujar
    {
        string Dibujar();
        string Definir();
    }

    public interface IDibujarHexagono
    {
        string Dibujar();
    }

    public class Hexagono : IDibujar, IDibujarHexagono
    {

        string IDibujar.Dibujar()
        {
            return "Implementacion del metodo Dibujar";
        }

        public string Definir()
        {
            return "Implementacion del metodo Definir";
        }

        string IDibujarHexagono.Dibujar()
        {
            return "Implementacion del metodo Dibujar Vertices";
        }
    }

Se puede ver nuestra clase implementa dos interfaces distintas. Algo que hablando de clases no se puede hacer ya que sabemos que en C# esta prohibido la herencia multiple. Otro punto clave que podemos ver en este ejemplo es que se puede hacer un llamado explícito de que interface estamos definiendo que método. Podemos ver que el método Dibujar esta definido en dos interfaces distintas que nuestra clase Hexagono esta implementando. Por este motivo estamos explicando de que interface estamos definiendo que método. Para poder utilizar uno u el otro deberíamos hacerlo mediante el uso de cast para cada interface. La forma en la que se utiliza lo podemos ver en el siguiente ejemplo.

            var hexa = new Hexagono();

            IDibujar test1 = (IDibujar) hexa;
            Console.WriteLine(test1.Dibujar());
            IDibujarHexagono test2 = (IDibujarHexagono)hexa;
            Console.WriteLine(test2.Dibujar());

Las diferencias


Habiendo explicado ambos podemos ver que ambas opciones nos ofrecer un mecanismo para definir comportamiento. Las interfaces sobre las clases abstractas nos brindan la posibilidad de implementar mas de una interface mientras que solo podemos derivar de una clase abstracta por vez. En este sentido las interfaces nos brindan mas flexibilidad a la hora de definir comportamiento. Como contrapartida sobre las interfaces podemos decir que estas son implementaciones de "todo o nada" lo que quiere decir que cuando implementamos una interface debemos definir todos los métodos que esta define. Las interfaces como bien ya dijimos a diferencia de las clases abstractas estas no definen comportamiento para los contratos que definen.

Para cerrar cabe aclarar que a la respuesta de qué conviene utilizar se puede responder que depende de las circunstancias. Por esto es importante que expliquemos cuales son los pro y contra de cada una de las herramientas y en que aspecto conviene utilizar una u otra.

No hay comentarios:

Publicar un comentario