htm=articulo/comher.htm ok articulo/comher.htm Herencia ? NO, gracias !

Herencia ? NO, gracias !

COM no soporta herencia, pero hasta que punto es imprescindible la herencia en un modelo de objetos como COM ?


Que es eso llamado herencia ?

    En la Programacion Orientada a Objeto (POO), la herencia es el mecanismo que implementa el polimorfismo y la reutilizacion de código. Es decir, la herencia en sí misma no es un objetivo buscado en la POO. Los objetivos buscados en la POO son, por un lado, el polimorfirmo de los objetos y, por otro lado, la reutilizacion del código.

En POO, el polimorfismo significa que se puede trabajar sobre un objeto sin saber exactamente qué tipo de objeto es. Supongamos que tenemos un objeto Animal, y tenemos un método Alimentar capaz de llevar a cabo determinadas acciones sobre el objeto Animal.

Supongamos ahora que tenemos otros objetos Caballo, Perro, etc... Si estos objetos implementan polimorfismo respecto al objeto Animal, el método Alimentar trabajará perfectamente sobre ellos. Observesé que el método Alimentar no tiene conocimiento de estar trabajado sobre un objeto de tipo distinto a la clase Animal.

    Muchos lenguajes consiguen el polimorfismo por medio de la herencia. Se crea una clase Animal y un método Alimentar. Luego se crean nuevas clases Caballo, Perro, etc.. que se derivan (heredan) de la clase Animal. Automáticamente, el método Alimentar trabaja perfectamente sobre las nuevas clases. Y eso que el método Alimentar se creó cuando todavía no existían estas nuevas clases.

La herencia proporciona tambien la reutilizacion del código. En el ejemplo anterior, al clase Animal puede implementar una serie de métodos miembro (Comer, Dormir, etc...), al crear nuevas clases por herencia de Animal, estas nuevas clases nacen ya con los métodos miembro de su clase base, sin necesidad de escribir nuevos métodos miembro.

Problemas con la herencia.

    En ocasiones es preciso que un objeto presente polimorfismo respecto a dos o más clases base. Supongamos que tenemos la clase Cuadrupedo y la clase Mamifero. Estas clases no derivan una de la otra puesto que no todos los mamíferos son cuadrúpedos ni todos los cuadrúpedos son mamíferos. Si vamos a crear una clase Vaca, seguramente querremos que la clase Vaca presente polimorfismo tanto respecto a la clase Cuadrupedo como respecto a la clase Mamifero.

Existen lenguajes, C++ es uno de ellos, que soportan herencia múltiple. Esto es, se puede derivar perfectamente el objeto Vaca de dos objetos base simultaneamente, los objetos Mamifero y Cuadrupedo.

    La herencia múltiple resulta, sin embargo, problemática. Supongamos que tanto el objeto Mamífero como el objeto Cuadrupedo derivan de una clase base común, la clase Animal. Tenemos ahora que la clase Vaca deriva de Animal por dos vías distintas. Esto presenta un problema para el compilador ya que existen dos modos diferentes de convertir una referencia al objeto Vaca en una referencia al objeto Animal. La implementacion del polimorfismo múltiple por medio de la herencia multiple es una fuente continua de errores.

Existe otro problema menor relacionado con la herencia. Si creamos una clase por herencia de otra, el código de la clase padre se incluye en el programa incluso en el caso de que nunca se vaya a usar. Es decir, la reutilizacion del código puede ser deseable, pero en ocasiones se sobrecargan los métodos de la clase derivada ya que se busca el polimorfismo pero nó la reutilizacion del código. Con la herencia ambas caracteristicas van unidas, el código de la clase base estará presente aunque no se use realmente.


El polimorfismo en el modelo COM.

    En el modelo de objetos COM, no existe la herencia. Los objetos COM implementan interfaces y son los interfaces los que proporcionan polimorfismo. El polimorfismo que proporcionan los interfaces no presenta ninguna desventaja respecto al proporcionado por la herencia. Al contrario, en las tecnologías que precisan la implementacion de gran numero de interfaces se ve la ventaja que representan estos sobre la herencia.

Por ejemplo, los controles OCX usados en varios lenguajes (principalmente Visual Basic) implementan típicamente una decena de interfaces. Tenemos controles visibles e invisibles en tiempo de ejecucion, con acceso a datos enlazados o sin él, que usan una ventana de windows o usan la ventana del contenedor, con o sin generación de eventos, etc...

Combinar todas estas caracteristicas en un arbol de herencia resulta complicado, sin embargo aplicar el mecanismo de las interfaces resulta trivial. Por ejemplo, tenemos un control OCX que no puede enlazarse a datos y queremos añadirle esta capacidad, solo tenemos que añadir al control el interface correspondiente. O a la inversa, tenemos un objeto enlazado a datos que no es un control y queremos convertirlo en control, añadimos un interface y ya tenemos un control, que queremos que ese objeto sea visible, añadimos otro interface.

    Al manejar objetos COM debemos olvidar las relaciones de herencia. Por ejemplo, el objeto Perro es un objeto Animal (Perro deriva de Animal). En lugar de lo anterior, debemos considerar el comportamiento del objeto. Este objeto implementa el interface Animal ?, y el interface Cuadrupedo ? y el interface Vaca ? La implementacion o nó de un interface nos dice si el objeto puede comportarse o nó de una determinada manera. Si implementa el interface Animal, puede comportarse como un objeto Animal, si implementa el interface Cuadrupedo puede comportarse como un objeto Cuadrupedo, etc...

    Al crear objetos COM no se producen los mismo problemas que plantea la herencia multiple. Simplemnte, debemos definir interfaces para cada rol que pueda tener un objeto y luego, al crear un objeto, debemos elegir cuales son los interfaces que debe implementar ese objeto.


La reutilizacion del código bajo COM.

    Hemos visto que la ausencia de herencia en el modelo de objetos COM no supone un inconveniente en cuanto a la implementación del polimorfismo, pero ¿ que pasa con la reutilizacion del código ?

La implementacion de interfaces en un objeto COM no supone reutilización del código. Por ejemplo, si el objeto Vaca implementa las interfaces Animal, Cuadrupedo, Mamifero, ... es necesario escribir el código que sea necesario para realizar esta implementación. Cuando creamos otro objeto que implementa los mismos interfaces debemos reescribir de nuevo el código de los interfaces.

    Sin embargo, bajo COM es posible reutilizar código por medio de un mecanismo llamado agregación. Cuando queremos reutilizar el codigo de un objeto para que lo use otro objeto sin necesidad de reescribir el código, proceremos a agregar al segundo objeto una instancia del primer objeto.

    La agregación tiene ventajas e inconvenientes respecto a la herencia. Como principal ventaja, la agregacion ahorra recursos cuando no se piensa reutilizar código ya que en la herencia siempre se prouce la instanciación del objeto base mientras en la agregacion solo se hace cuando es necesario. A favor de la herencia juego el hecho de que la agregacion la debe hacer manualmente el programador mientras que en la herencia el trabajo lo hace el compilador.

En cualquier caso, el modo en el que se reutiliza el código es el mismo en la herencia y en la agregación , la diferencia estriba en que en el caso de la herencia todo el trabajo lo hace el compilador mientras que la agregacion la realiza el programador.


© info3@maicas.net