PDA

Ver la versión completa : Sobre C++ y las interfaces de clases



efegea
18/07/2007, 20:24
No acabo de entender del todo lo de las interfaces de clases, y no consigo encontrar nada en todo internet que lo explique.

Sé lo que es y sé usarlas, pero no acabo de ver el porqué se usan y en qué clases debo usarlas y en cuáles no

Estoy mirando el código de Irrlicht, un motor 3D open source, y usa mucho las interfaces.


Obviamente cuando digo interfaz no me refiero a un GUI sino a una clase base de donde derivan otras clases y que luego se usa como "interfaz" de esas clases derivadas. O algo así :D

cdrman
18/07/2007, 20:28
Yo no es ke sea tampoco un genio, ni mucho menos. PEro por ejemplo tu tienes en tu programa un sitio donde por ejemplo cargaras filtros, el problema viene ke si tu un dia de estos creas un filtro n podrias instanciarlo, porque tendria ke ser de la clase filtro, otra cosa seria si tubieses una interface filtro, y cada filtro nuevo que creees herede de esa interface, por lo que se consigue una mejor abstraccion. No se como explicarlo, pero lo he utilizado para programar sobre webs cams con filtros de imagenes.

Entiendes?

efegea
18/07/2007, 20:34
Sí, cdrman, lo entiendo, eso si lo sabía.

La culpa es de Irrlicht que me tiene confundido :lol:

Es que veras, estoy viendo las clases que voy a implementar en mi motor, y claro en cada una me pregunto ¿le hago un interfaz o declaro directamente la clase? Y voy a mirar el código de Irrlicht para "inspirarme" y ahí es cuando me lio "der tó"

Esa es la cuestión que me tiene bloqueado, que no sé en cuales hacer un interfaz.

anibarro
18/07/2007, 21:32
Usar o no clases abstractas para definir interfaces es mas una cuestion de diseño o de estilo que de necesidad.
Si por ejemplo tienes varias clases semanticamente parecidas (por ejemplo las clases Moto, Coche, Furgoneta y Camion), y necesitas ciertas funciones de todas ellas porque las usas para algun tipo de calculo, por ejemplo "getNumeroRuedas", te vendria bien definir una interfaz con esos metodos que necesitas y hacer que todas las clases de ese tipo que se añadan, sean hijas de esa interfaz, asegurandote que definen todo lo que necesitas

Aiken
18/07/2007, 22:05
yo creo: objetos con las mismas funciones (mismo interface), pero que intermamente esas funciones estan programadas diferente, pues tienes que crear un interface "clase abstracta" con las funciones vacias (pues son diferentes para cada hijo)

si las funciones intermamente son diferentes no hay manera de agruparlas de ninguna forma.
bueno si sobreescribiendo los metodos. Pero que metodos pones en la clase padre? los del coche, los de la moto? pongas lo que pongas solo van a valer para 1 de las clases hijas, asi que para que ponerlas, directamente creas todas como hijas, no? :)

Aiken

anibarro
18/07/2007, 22:31
si las funciones intermamente son diferentes no hay manera de agruparlas de ninguna forma.
bueno si sobreescribiendo los metodos. Pero que metodos pones en la clase padre? los del coche, los de la moto? pongas lo que pongas solo van a valer para 1 de las clases hijas, asi que para que ponerlas, directamente creas todas como hijas, no? :)
Aiken, no tienes que redefinir ningun metodo, en la clase abstracta estan vacios para obligar a definirlos en la clase hija. En la clase padre pondras los metodos comunes a todas las clases que heredan, por ejemplo todos las clases que heredan de la clase abstracta "vehiculo", compartiran unas caracteristicas como pueden ser tener ruedas, tener motor, velocidad maxima, etc...
Podras extender los atributos y metodos para las clases hija especializandolos, pero heredando de una interfaz te aseguras que los metodos que consideraste necesarios cuando lo diseñaste, esten disponibles en todas las subclases

WinterN
18/07/2007, 22:47
Yo si quieres te lo explico desde el punto de vista Java, que es muy similar. Al final es una cuestión más de concepto que práctica.

Un interfaz es básicamente una definición de lo que puede hacer una clase, pero en ningún caso de cómo debe hacerlo; y esa es la principal diferencia entre un interfaz y una super-clase.

Mejor veamos unos ejemplo. Supongamos que tenemos la clase VehículoTerrestre con los métodos acelerar(), frenar(), numeroDeRuedas(), etc. Luego tendrá subclases que serán Coche, Bicicleta, Tren...

En este caso se trataría de una clase abstracta, ya que por ejemplo los métodos acelerar() y frenar() serían comunes a todas las instancias. En cualquier vehículo acelerar aumenta la velidad y frenar la disminuye. En cambio otros métodos como obtener el número de ruedas o el peso deberían ser implementados por cada hijo, ya que serían distintos.

Un caso de interfaz se aplica más bien cuando no sabemos el resultado que va a tener un método, o que debe hacer. Por ejemplo podríamos tener el interfaz StreamOut como un canal de salida, con un método put(char* texto). Cualquier clase que implemente ese método sabemos que podemos meterle textos, pero no sabemos nunca lo que va a hacer con ellos. Así, podemos tener una clase que los envíe a la impresora, otra que los pase a un PDF, otra que los saque por pantalla, otra que los diga por el altavoz, o enviarlo por email...

Otra forma de verlo es que un interfaz es como un protocolo de comunicación entre dos clases. Por ejemplo, una clase que represente una figura 3D quiza necesite tener implementados los métodos rotar() escalar() y dibujar(), para que el motor central del programa pueda trabajar con ella. De este modo el interfaz Figura3D sería un protocolo con los requisitos que debe cumplir una clase para poder ser tratada como una figura por el motor. Al motor lo que le importa es que le llegue una clase con esos métodos, y le da igual que sea la clase Punto, la clase Triangulo, la clase Torus o la clase NaveEspacialTexturizada, siempre que implemente los métodos definidos por el interfaz.

Aiken
18/07/2007, 22:54
Aiken, no tienes que redefinir ningun metodo, en la clase abstracta estan vacios para obligar a definirlos en la clase hija. En la clase padre pondras los metodos comunes a todas las clases que heredan, por ejemplo todos las clases que heredan de la clase abstracta "vehiculo", compartiran unas caracteristicas como pueden ser tener ruedas, tener motor, velocidad maxima, etc...
Podras extender los atributos y metodos para las clases hija especializandolos, pero heredando de una interfaz te aseguras que los metodos que consideraste necesarios cuando lo diseñaste, esten disponibles en todas las subclases


Tan mal me he explicado :D Justo eso es lo que he dicho (o intentado decir) yo :D

Que como son comunes en interfaz pero diferentes en codigo, pues creas una abstracta para obligarte a definirlas en los hijos y a la vez obligarte a definirlas con el mismo interface no? :D


Aiken

< - >
por lo que decis, que casi siempre es de estilo no de necesidad ... creo que en el caso que os digo, que los metodos son comunes pero implementados internamente diferentes se hace absolutamente necesaria una clase abstracta.

Aiken

anibarro
18/07/2007, 23:00
Soy yo q no leo xD

Aiken
18/07/2007, 23:04
Mejor veamos unos ejemplo. Supongamos que tenemos la clase VehículoTerrestre con los métodos acelerar(), frenar(), numeroDeRuedas(), etc. Luego tendrá subclases que serán Coche, Bicicleta, Tren...


muy buen ejemplo.

VehiculoTerrestre. Porque es abstracta? Respuesta: sabriais programar el metodo contarruedas() de esta clase? No, pues necesitarias saber que tipo de vehiculo es. Luego el metodo estaria vacio, y seria los coches(), motos() etc los que tendrian los metodos implementados.

Resumiendo. Podriamos decir, que si necesitais/quereis agrupar los objetos en una clase superior, y esa clase superior es tan generica que no podeis definirle metodos, pues cae por su peso que es una clase abstracta por necesidad :D

Aiken

WinterN
18/07/2007, 23:10
Otra razón por la que usar interfaces es para evitar la temida herencia múltiple que según algunos programadores, quita elegancia al código, trae problemas como las dependencias cíclicas y lo hace más dificil de comprender.

< - >

muy buen ejemplo.

Sin haber leído su comentario hasta ahora, he ido a poner el mismo que anibarro :D Supongo que es el ejemplo que vienen en todos los libros.

efegea
19/07/2007, 14:59
Gracias a todos por las respuestas.

Ahora hay algo que si que no se: &#191;como integrar un singleton en una interfaz de clase?

Es decir, tengo una interfaz y quiero que las clases derivadas de ella sean un singleton.

&#191;Se puede hacer? :confused:

romeroca
19/07/2007, 18:04
Te recomiendo que mires el siguiente art&#237;culo en la wikipedia

http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o_Singleton

Explican bastante bien el patr&#243;n e incluso hay ejemplos.

efegea
19/07/2007, 19:29
Te recomiendo que mires el siguiente artículo en la wikipedia

http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o_Singleton

Explican bastante bien el patrón e incluso hay ejemplos.

ufff..¿pero hay que usar templates? yo es que de eso ni idea, preferiría hacerlo sin templates, aunque si no hay mas remedio..

swapd0
19/07/2007, 20:42
Para el patron singleton no hace falta ni usar templates ni interfaces, creo que es como matar moscas a ca&#241;onazos. Ademas, la version de los templates nadie te obliga a que no puedas crear un objeto de la clase que le pasas al template...

efegea
19/07/2007, 23:16
Pues ni idea de como implementar un singleton como clase abstracta sin usar templates.

Ayudita porfa plis :D

EDIT: bueno me he puesto por mi cuenta..y creo que lo he conseguido :) Eso si, no como clase abstracta, pero bueno..lo he implementado en cada clase derivada y listo

WinterN
20/07/2007, 01:57
A mi es que los conceptos de clase abstracta y singleton me parecen incompatibles a nivel l&#243;gico. Me explico:

- Clase abstracta: Clase que no se puede instanciar
- Clase singleton: Clase de la que s&#243;lo se puede obtener una instancia.

Seg&#250;n mi punto de vista, una clase abstracta no es ni Singleton, ni deja de serlo. Creo que entiendo m&#225;s o menos lo que quieres hacer, y no sabr&#237;a darte una soluci&#243;n sin una visi&#243;n un poco m&#225;s explicativa del problema.

efegea
20/07/2007, 09:01
A mi es que los conceptos de clase abstracta y singleton me parecen incompatibles a nivel lógico. Me explico:

- Clase abstracta: Clase que no se puede instanciar
- Clase singleton: Clase de la que sólo se puede obtener una instancia.

Según mi punto de vista, una clase abstracta no es ni Singleton, ni deja de serlo. Creo que entiendo más o menos lo que quieres hacer, y no sabría darte una solución sin una visión un poco más explicativa del problema.

Lo digo porque, si te fijas en los ejemplos de la wikipedia, lo que hace es hacer una clase abstracta como singleton para luego derivar de ella. Obviamente la abstracta no se puede instanciar, pero la derivada es un singleton. No se si me explico.

De todos modos no importa, ya lo he conseguido de otra forma :brindis:

WinterN
20/07/2007, 11:10
La verdad es que no me acuerdo como iban los Templates de C++ :rolleyes:

swapd0
21/07/2007, 19:37
Para hacer una clase singleton solo tienes que poner el constructor como protegido, asi no se podra crear instancias de esta clase y poner un metodo de clase (static) que te devuelva un objeto de la clase. Para que quede mas claro:


class CFoo
{
public:
static CFoo & instancia() // devuelve un objeto foo
{
static CFoo instancia;
return instancia;
}
...
protected:
CFoo();

};

Hay otra version que va con punteros, que es la que suelo implementar.
La ventaja de esta version (respecto a la version con templates) es que es imposible crear objetos de la clase Foo, solo tendras uno, mientras que la version con templates siempre puedes crear un objeto del parametro del template.

efegea
21/07/2007, 20:43
swapd0, es as&#237; exactamente como lo hab&#237;a implementado yo por mi cuenta :)

DMusta1ne
25/07/2007, 12:24
Leyendo en una web sobre los patrones evaluativos GRASP (que sirven para evaluar el dise&#241;o de una aplicacion orientada a objetos) he encontrado una frase curiosa sobra las interfaces

"En java, pensar en interfaces nos fuerza a que nuestros sistemas sigan los principios de alta cohesi&#243;n. En alg&#250;n sitio le&#237; que una aplicaci&#243;n con menos de 8 interfaces no utiliza correctamente los conceptos de orientaci&#243;n a objeto ... y estoy de acuerdo ...."

Quiz&#225;s eso no resuelva mucho sobre el uso de interfaces, pero me pareci&#243; una frase curiosa (link aqu&#237; (http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=grasp), mirar Alta Cohesi&#243;n).

Sobre el patr&#243;n Singleton, tengo en mis apuntes dos maneras de implementarlo. Una que es como puso swapd0 (yo lo pongo en java, ni papa de C++ xDD)

El primero que es el que hab&#233;is puesto (aunque parece una mezcla de los dos)

public class T{
private static T instance =new T();

private T() {...}

public static T getInstance(){

return instance;
}
//los m&#233;todos de la clase T
}
se define un atributo est&#225;tico y privado tipo clase T, solo accesible por la propia clase, y un m&#233;todo p&#250;blico para acceder a el


public class T{
private static T instance =null;

//el constructor normal de la clase T con visibilidad privada para que solo la misma clase pueda acceder a el
private T() {...}

public static T getInstance(){
if(instance==null)
intance=new T();
return instance;
}
//los m&#233;todos de la clase T
}
Y luego esta otra manera, el m&#233;todo p&#250;blico comprueba si hay o no instancia de T, y si no la hay la devuelve.

Se que llego con retraso, pero lo estaba estudiando y me acord&#233; ^^

NoobLuck
02/09/2007, 18:02
Respecto al tema inicial del hilo, tal vez se os ha olvidado mencionar que en java no hay herencia múltiple, las clases sólo pueden tener una clase madre. Aunque pueden tener diversos interfaces.

Un interfaz se usaria por ejeplo para hacer a una clase serializable permitiendo por ejemplo guardarla en un fichero y despues recuperarla con una serie de métodos. Este es un uso claro de una interfaz.