Uno de mis roles profesionales es el de entrevistador técnico de candidatos a nuevos
codificadores, esto es, evaluar las capacidades técnicas y las posibilidades que
tienen los candidatos de convertirse en programadores estrella en un futuro. En
mi caso hago las entrevistas relativas al uso de C#.
Entre las preguntas que hago, hay una que espero impaciente y casi siempre realizo
con una sonrisa, la pregunta es “¿Me podría explicar en qué se diferencia las interfaces
de las clases abstractas?”.
Las principales repuestas que recibo son:
-"Una clase abstracta tiene código y una interfaz no"
Lo cual es bastante impreciso, porque para empezar, ¿acaso las declaraciones no
son código?
-"Las Interfaces sirve para implementar la herencia múltiple"
Esto es relativo. El concepto de herencia, implica “heredar” comportamiento, lo
cual no se consigue con las interfaces, con lo que el tema de la “herencia múltiple”
seguiría sin ser preciso, en todo caso heredamos la “posibilidad” de comportarnos
como la clase padre, pero no el comportamiento en sí.
-"Las Interfaces representan un contrato que se debe cumplir"
lo cual es cierto y muy aproximado, pero muy de libro. Queda en el aire la verdadera
necesidad de las interfaces.
-"La clase abstracta tiene métodos que deben ser implementados en las clases hijas"
Cierto, pero sigue sin quedar claro el motivo, y es otro enfoque de la aplicación
anterior.
¿Qué es lo que realmente se está esperando?
Lo primero la pregunta es capciosa. Lo objetivos de las interfaces y las clases
abstractas, aunque podrían resultar parecidos, no lo son en verdad y tanto una como
otra, pueden explicarse sin ser comparadas entre ellas.
Casi todas las respuestas son, técnicamente hablando, correctas, pero no se busca
que el candidato sepa de memoria que es una cosa o la otra, si no intentar vislumbrar
su experiencia profesional y su capacidad de razonamiento.
Las interfaces y clases abstractas son elementos que son “olvidados” por muchos
programadores en su vida profesional, pero ambos nos permiten solucionar problemas
complejos de herencia y reutilización de una manera clara y ordenada. Un programador
con algo de experiencia, que haya desarrollado un programa empresarial de mediano
tamaño, se habrá encontrado con dichos problemas, y si no ha usado interfaces o
clases abstractas, puede ser debido a varias cosas:
- Realmente el programa no lo necesita, con lo que no sería un programa tan “grande”, lo cual puede arrojar datos sobre la experiencia del candidato.
- Enredo el código de tal manera, que efectivamente no lo necesito, pero creo un código difícil de entender y ampliar (lo cual no es deseable, pues que va a cambiar y se va a mantener).
- Una variación anterior, es que no hizo realmente un programa orientado a objetos, sino, un programa estructurado, con lo que no tuvo que enfrentarse a ningún problema relacionado con la programación orientada a objetos (esta problema es el más común).
- Otro de los motivos de realizar esta pregunta, es analizar la respuesta del candidato, en cuanto a si esta es demasiado “académica”, o puede exponer un ejemplo por sí mismo (sin preguntarle). En el primer caso estaría demostrándome lo que sabe, en el segundo, estaría intentando resolver mi duda, lo cual marcaria una diferencia en un contexto real, porque habría demostrado, que sabe que lo importante son los por qué y no los cómo (lo importante es que hace y no como).
Ahora bien, veamos que es una cosa y la otra.
¿Qué es una clase abstracta?
Es una clase de cual no tiene sentido que se creen objetos, puesto que representa
una colección de conceptos abstractos, que no adquieren verdadera identidad hasta
que se herede, y se convierta en un elemento concreto.
La clase abstracta debe tener la mayor parte del “flujo de operación” que debe realizar
el objeto, pero no tiene determinadas partes o “trozos” de comportamiento, que pudieran
variar según la circunstancia, y allí viene la parte de la “abstracción”. Estas
partes (ubicadas generalmente en métodos), se dejaron vacías, esperando que alguien
herede la clase, y “concrete” la funcionalidad requerida en la clase hija.
¿Qué es una interfaz?
Una Interfaz por otro lado, define una serie de características que debe cumplir
una clase, que será usada a su vez por otros métodos o clases. Aquí la necesidad
es garantizar que nuestros objetos pueden realizar una determina acción, aunque
no nos importa como la realiza, ni siquiera tiene que realizar de forma semejante
a otras clases que implementen esa interfaz. En la interfaces se aplica la regla
Lo importante es el "Que hace" y no el "Como lo hace"
Próximamente hablaremos con más detalle de ejemplo de interfaces y clases abstractas,