Implementar una interface es establecer un contrato entre dos bloques de código, donde el bloque que implementa la interface se compromete a implementar concretamente los métodos que la interface implementada define.
En principio esto a veces suena raro. La pregunta que surge es ¿no me estaré complicando la vida?… depende…
Supongamos que en el marco de un proceso tenemos un conjunto de objetos heterogéneos que desconocemos. Algunos tienen un método de serialización de nombre Save, si el método existe, es el encargado de persistit al objeto. Si no existe el método Save, el objeto se persiste en base de datos por medio de otro método.
La pregunta es ¿cómo preguntar, en tiempo de ejecución, si un objeto implementa un método de un determinado nombre?Lo que sigue intenta responder esto. Para desarrollar este ejemplo, hay que abrir Visual Studio y crear un proyecto de Windows de Consola en Visual Basic o C#.
Ahora creamos la interface ISerializable, que contiene la función Save que devuelve un boolean:
[VB]
Public Interface ISerializable
Function Save() As Boolean
End Interface
[C#]
using System;
interface ISerializable
{
bool Save();
}
Por convención a los nombres de las interfaces se les prefija una “I” para una mejor identificación.
Luego vamos a crear una clase, de nombre Controlcito, con una única propiedad llamada Datos de tipo string:
[VB]
Public Class Controlcito
Private mDatos As String
Public Property Datos() As String
Get
Return mDatos
End Get
Set(ByVal value As String)
mDatos = value
End Set
End Property
End Class
[C#]
using System;
public class Controlcito
{
protected string Data;
public string data
{
get
{
return this.Data;
}
set
{
this.Data = value;
}
}
}
Defino ahora un control, con nombre miControl, que herede de Controlcito e implemente la interface ISerializable
[VB]
Public Class miControl
Inherits Controlcito
Implements ISerializable
Public Sub New()
Datos = «Estos son los datos de prueba…»
End Sub
Public Function Save() As Boolean
Implements ISerializable.Save
Console.WriteLine(«Grabando…{0}», Datos)
Return True
End Function
End Class
[C#]
using System;
class miControl : Controlcito, IValidate, ISerializable
{
public miControl()
{
data = «Mis datos de prueba.»;
}
public bool Save()
{
Console.WriteLine(«Grabando…{0}», data);
return true;
}
}
De esta forma queda implementado, efectivamente, el método Save de la interface ISerializable. Verán que al tipear la linea de código referida a la implementación de la interface, cuando se hace click en Enter, Visual Studio escribe el encabezado de la función que define la interface.
Ya sabemos cómo implementar una Interface.
Ahora el problema es saber, programáticamente, si una clase implementa una Interface. Para el ejemplo que estamos viendo, en términos concretos, es saber si la clase tiene implementado un método Save, en otras palabras, si la clase implementa algún método de serialización.
Entonces vamos a escribir la aplicación que se lanzará en consola, la llamamos App
[VB]
Module App
Sub Main()
Console.WriteLine(«Versión Visual Basic»)
Dim miControl As New miControl
Dim ser As ISerializable = DirectCast(miControl, ISerializable)
Dim exito As Boolean = ser.Save
Console.WriteLine(«La validación de ‘{0}’ {1} fue correcta», miControl.Datos, IIf(exito, «», «no»))
End Sub
Console.ReadLine()
End Module
[C#]
class App
{
public static void Main()
{
Console.WriteLine(«Versión C#»);
miControl miControl = new miControl();
ISerializable ser = (ISerializable)miControl;
bool exito = ser.Save();
Console.WriteLine(«La validación de ‘{0}’ {1} fue correcta», miControl.data, (true == exito ? «» : «no»));
}
Console.ReadLine();
}
Esto parece funcionar, pero si la interface no está implementada DirectCast(miControl, ISerializable), en VB, o (ISerializable)miControl, en C#, ambos, en ese caso dan error.
La forma correcta de preguntar es TypeOf (miControl) Is ISerializable, en VB, o miControl Is ISerializable, en C#. Veamos:
[VB]
Module App
Sub Main()
Console.WriteLine(«Versión Visual Basic»)
Dim miControl As New miControl
If TypeOf (miControl) Is ISerializable Then
Dim ser As ISerializable = DirectCast(miControl, ISerializable)
Dim otroExito As Boolean = ser.Save
Console.WriteLine(«Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente», miControl.Datos, IIf(otroExito, «», «no»))
End If
Console.ReadLine()
End Sub
End Module
[C#]
class App
{
public static void Main()
{
Console.WriteLine(«Versión C#»);
miControl miControl = new miControl();
if (miControl is ISerializable)
{
ISerializable ser = (ISerializable)miControl;
bool otroExito = ser.Save();
Console.WriteLine(«Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente», miControl.data, (true == otroExito ? «» : «no»));
}
Console.ReadLine();
}
}
Esto funciona correctamente en ambos lenguajes. Pero existe una forma optimizada, en términos de código MSIL.
En VB se usa TryCast que evalúa si la interface está implementada, si no lo está, no devuelve error sino Nothing. En C# esto es análogo con el operador as.
[VB]
Module App
Sub Main()
Console.WriteLine(«Versión Visual Basic»)
Dim miControl As New miControl
Dim serial As ISerializable = TryCast(miControl, ISerializable)
If Not serial Is Nothing Then
Dim otroExitoMas As Boolean = serial.Save
Console.WriteLine(«Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente, con una versión optimizada», miControl.Datos, IIf(otroExitoMas, «», «no»))
End If
Console.ReadLine()
End Sub
End Module
[C#]
class App
{
public static void Main()
{
Console.WriteLine(«Versión C#»);
miControl miControl = new miControl();
ISerializable serial = miControl as ISerializable;
if (null != serial)
{
bool otroExitoMas = serial.Save();
Console.WriteLine(«Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente, con una versión optimizada», miControl.data, (true == otroExitoMas ? «» : «no»));
}
Console.ReadLine();
}
}
La solución, con los proyectos de ejemplo pueden descargarse de Interfaces.zip.
Ojalá haya servido de algo. 🙂
25 comentarios
Comments feed for this article
miércoles 13 \13-03:00 agosto \13-03:00 2008 a 13:08:45
Victor
Gracias por tu aporte, en estos momentos me encuentro estudiando para los examenes desarrollador 5 estrellas de microsoft, en estrella 0 y tus notas son de gran ayuda, puesto que le estoy entrando a la programación desde sus definiciones hasta su puesta en práctica, mi meta es poder códificar con verdadero conocimiento de lo que se está haciendo y no copiando y pegando, eso podría venir después.
Veo algo importante en el inicio de tu página, Arquitectura, ingeniería y desarrollo de software. Tres cosas que intrinsicamente se encuentran relacionadas y que me da la visión de un todo «Un Buen Sistema»
Saludos Carlos…
viernes 15 \15-03:00 agosto \15-03:00 2008 a 15:08:28
Carlos Marcelo Santos
Gracias Víctor:
Es una alegría que te resulte útil lo que escribo.
Me recuerda que llevo un tiempo sin escribir 😉
¡Suerte con tus exámenes!
jueves 13 \13-03:00 noviembre \13-03:00 2008 a 13:11:27
YG
muy bueno lo que escribiste, me sirvio muchio para un trabajo practico de la facu.
GRACIAS.!
jueves 13 \13-03:00 noviembre \13-03:00 2008 a 14:11:27
Carlos Marcelo Santos
¡Qué alegría me das! Creo que cuando te recibas me podrías invitar con una cerveza jajaja….
Saludos.
martes 27 \27-03:00 enero \27-03:00 2009 a 13:01:23
mat123
Enhorabuena por el código.
Me ha servido de gran ayuda
S2
miércoles 28 \28-03:00 enero \28-03:00 2009 a 1:01:46
Carlos Marcelo Santos
¡Qué alegría me da tu comentario! Te mando un abrazo a través del oceano 🙂
martes 07 \07-03:00 abril \07-03:00 2009 a 18:04:46
gerardo
que buena clase, me servirá de mucho en la uni ya que ese tema lo he empezado a llevar.
muchas gracias
miércoles 08 \08-03:00 abril \08-03:00 2009 a 20:04:04
Carlos Marcelo Santos
Gracias Gerardo. ¡Suerte en tu carrera!
domingo 26 \26-03:00 abril \26-03:00 2009 a 13:04:56
Moises
Carlos interesante codigo…sabes soy un aficionado a la programacion, es decir, no he estudiado programacion en ningun centro de estudios todo lo que he aprendido lo he hecho gracias a internet y bueno tengo algunas nociones de clases pero esto de las interfaces no, tendras por ahi algun tutorial o algo parecido que abarque todo lo de las clases, enumeraciones, clases abastractas, interfaces…. y lo mas importantes cuando usar cada una de ellas….si tuvieras algo seria de gran ayuda…
Espero tener una buena acogida a mi interrogante…
ATTE.
Moises Cornejo
San Antonio, Chile
lunes 27 \27-03:00 abril \27-03:00 2009 a 12:04:49
Carlos Marcelo Santos
Hola Moises: Qué bueno que te sirva la nota. Te recomiendo estos dos libros
Inside C#, (http://www.amazon.com/Inside-C-Second-Tom-Archer/dp/0735616485/ref=sr_1_1?ie=UTF8&s=books&qid=1240843876&sr=1-1)
Autor: Tom Archer (http://blogs.msdn.com/tomarcher/)
Este está editado en castellano.
Pro C# 2008 and the .NET 3.5 Platform (http://www.amazon.com/2008-NET-Platform-Fourth-Windows-Net/dp/1590598849/ref=pd_sim_b_6)
Autor: Andrew Troelsen (http://andrewtroelsen.blogspot.com/)
Vas a encontrar quien te recomiende otros, hay muchísimos buenos libros. A mi estos dos me sirvieron de mucho.
Un saludo a través de la cordillera.
martes 27 \27-03:00 octubre \27-03:00 2009 a 17:10:35
Juan Carlos
Interesante post, gracias por publicarlo aprendí lo importante y básico
martes 27 \27-03:00 octubre \27-03:00 2009 a 17:10:41
Carlos Marcelo Santos
¡Brindo por eso!
domingo 01 \01-03:00 noviembre \01-03:00 2009 a 22:11:08
Dependency Injection « Carlos Marcelo Santos
[…] comencemos por escribir una interface que defina estos cuatro […]
martes 11 \11-03:00 May \11-03:00 2010 a 19:05:25
pedro
Hola soy nuevo utilizando cooperator, queria saber si me podes dar un ejemplo de como generar reportes utilizando varias entidades.
Desde ya muchas gracias y espero su pronta respuesta
miércoles 12 \12-03:00 May \12-03:00 2010 a 7:05:35
Carlos Marcelo Santos
Te pido disculpas Pedro, pero no estoy con tiempo para escribir lo que me pedís.
De todos modos, habría que ver con qué herramienta preferís manejarte y luego ver en que formato esta acepta la información.
El resto es generar la consulta con Cooperator y vincularla en tu herramienta, del mismo modo que harías sin Cooperator.
Saludos.
Carlos.
domingo 23 \23-03:00 May \23-03:00 2010 a 22:05:16
Rogelio
Disculpa si podrias realizar un pequeño ejercicio implementando varias clases con sus interfaces ya que no encuentro un ejercicio con estas caracteristicas y todas son muy basicas.
Tambien si me podrias indicar cual es la utilidad de implementar interfaces ya que bien podriamos realizar herencia de forma directa sobre las clases sin tener que realizar una interface.
Saludos
lunes 24 \24-03:00 May \24-03:00 2010 a 23:05:37
Carlos Marcelo Santos
Hola Rogelio, no tengo tiempo para escribir un ejemplo nuevo. Pero puedo comentarte que las interfaces son indispensables en muchos aspectos de la programación moderna. Por ejemplo en las técnicas de mocking, en WCF, en la aplicación de la mayoría de los patterns, IoC, dependency injection por interfaces, etc. Podrías evitar usar interfaces pero rapidamente vas a sentir la necesidad de aplicarlas.
martes 15 \15-03:00 junio \15-03:00 2010 a 23:06:22
grbr
Se agradece el aporte señor! 😀
Necesitaba saber como hacer interfaces en basic 😀 gracias! me salvaste la googleada
viernes 20 \20-03:00 agosto \20-03:00 2010 a 9:08:16
Alejandro
Quería saber de donde obtuviste la información de optimización de MSIL, con respecto al typeof y trycast. Existe alguna diferencia de utilizar «Not Objeto Is Nothing» a «Objeto IsNot Nothing»? Excelente articulo muy bien explicado
sábado 21 \21-03:00 agosto \21-03:00 2010 a 12:08:31
Carlos Marcelo Santos
Hola Alejandro, gracias por tus palabras.
Francamente no recuerdo dónde lo leí. Igualmente te recomiendo que uses Reflector, de Red Gate, acá tenés una versión libre, http://www.red-gate.com/products/reflector/ es muy fácil e intuitiva
Una vez que tengas esta herramienta, tendrías que hacerte un ejemplo que use typeof y otro con trycast, lo compiles y luego con Reflector podés descompilar la dll resultante en varios lenguajes, entre ellos MSIL. Del mismo modo con el not x is nothing vs isnot nothing y vas a poder comprobarlo vos mismo, sin que le lo venga a contar nadie, que intuyo, es lo que estás buscando. 😉
¡Qué lo disfrutes!
lunes 11 \11-03:00 octubre \11-03:00 2010 a 22:10:03
Moises
Hola, estoy aprendiendo a implementar clases e interfaces pero no habi podidio comprenderlo, gracias por el ejemplo
Saludos
sábado 14 \14-03:00 enero \14-03:00 2012 a 17:01:55
Juan Cristóbal Luis
Lamento lo tardío de mi comentario, pero sólo quería felicitarle, amigo Carlos. Me parece una maravilla lo que has colocado allí, pues luego de tanto tiempo, es ahora cuando logro entender ese asunto, y ello gracias a tu valioso aporte. Definitivamente, la vida es la obra maestra de Dios, más cuando se manifiesta en personas con tu forma de ser, es decir, no egoístas y deseosos de aportar algo para los demás. Saludos.
lunes 16 \16-03:00 enero \16-03:00 2012 a 0:01:11
Carlos Marcelo Santos
Amigo Juan, agradezco profundamente tus palabras, te envío un abrazo y ojalá algún día nos podamos conocer.
jueves 16 \16-03:00 febrero \16-03:00 2012 a 9:02:29
Andres Felipe
Excelente articulo, tal vez me podrias recomendar algun libro con el cual aprender ams del tema, especificamente en C#, estoy un poco perdido en esto de implementar interfases y clases. gracias
jueves 16 \16-03:00 febrero \16-03:00 2012 a 16:02:16
Carlos Marcelo Santos
Muchas Gracias Andrés. El de Andrew Troelsen es un libro que me gusta mucho, http://www.amazon.com/Pro-NET-Framework-Professional-Apress/dp/1430242337/ref=dp_ob_title_bk