No llamar al constructor de la clase base

19/01/2007 - 12:18 por emiliano.sutil | Informe spam
Hola a todos

Tengo un problemilla que me tiene un poco perplejo.

He leido que en C# cuando instancias un objeto de una clase, siempre
se llama al constructor de la clase base antes de lanzar el contructor
de la clase en cuestión.

¿Es eso correcto? mas que nada porque tengo una clase que hereda de
otra, pero no quiero que al instanciarla se llame al constructor del
ancestor.

¿Es eso posible? o estoy metiendo la pata en algún lado.

Un saludo

Emi

Preguntas similare

Leer las respuestas

#6 Ana Zuluaga
20/01/2007 - 14:21 | Informe spam
más aun como extraje ese
codigo distinto se me quedaron los 2 constructores iguales, asi que
eliminé el constructor de la clase hija. ¡ Que gran ejemplo del
refactoring en acción y sin
quererlo!



Puede ser pero, similar a lo que te sugieren, no estaría de más un rediseño
del modelo pensado al mantenimiento futuro.
Aunque te funcione bien, mientras más limpias y menos acopladas tengas tu
definición de clases te ahorrarás mucho trabajo posterior.

Ana
Respuesta Responder a este mensaje
#7 Roberto M. Oliva
21/01/2007 - 16:16 | Informe spam
Hola!

Como bien te dice Ana lo mejor es desacoplar las clases.
Por ello, la mejor solucion seria algo asi:

class Ancestor
{
protected tipoX _objeto;
public Ancestor(tipoX nuevo_objeto)
{
_objeto = nuevo_objeto:
}

}

class Base : Ancestor
{
public Base(tipoY nuevo_objeto) : base(nuevo_objeto)
{
}

}

Esto es lo que se llama Dependency of Injection y no es mas que todos
los objetos contenidos en una clase son pasados en el constructor y no
construidos por la misma.
Esto permite que a la larga las clases queden muy desacopladas
permitiendo evolucionarlas con el menor impacto en el resto.
Para ir un poco mas yo sacaria un interfaz (por ejemplo ITipo) que
implementan tanto la clase tipoX como, evidentemente, la clase tipoY,
quedando el codigo como sigue:

class Ancestor
{
protected ITipo _objeto;
public Ancestor(ITipo nuevo_objeto)
{
_objeto = nuevo_objeto:
}

}

class Base : Ancestor
{
public Base(ITipo nuevo_objeto) : base(nuevo_objeto)
{
}
}

Espero que todo esto te ayude

Por cierto, yo nunca delegaria en las clases heredadas la creacion del
estado inicial, por lo menos no en aquella parte que le corresponde a
la clase base. Osea, que en mi opinion, virtualizar el constructor no
me parece una buena idea.

Un saludo

Roberto M. Oliva


Ana Zuluaga wrote:
>más aun como extraje ese
>codigo distinto se me quedaron los 2 constructores iguales, asi que
>eliminé el constructor de la clase hija. ¡ Que gran ejemplo del
>refactoring en acción y sin
>quererlo!

Puede ser pero, similar a lo que te sugieren, no estaría de más un rediseño
del modelo pensado al mantenimiento futuro.
Aunque te funcione bien, mientras más limpias y menos acopladas tengas tu
definición de clases te ahorrarás mucho trabajo posterior.

Ana
Respuesta Responder a este mensaje
#8 emiliano.sutil
22/01/2007 - 09:19 | Informe spam
Roberto M. Oliva ha escrito:
Hola!




Hola.

Como bien te dice Ana lo mejor es desacoplar las clases.
Por ello, la mejor solucion seria algo asi:

class Ancestor
{
protected tipoX _objeto;
public Ancestor(tipoX nuevo_objeto)
{
_objeto = nuevo_objeto:
}

}

class Base : Ancestor
{
public Base(tipoY nuevo_objeto) : base(nuevo_objeto)
{
}

}

Esto es lo que se llama Dependency of Injection y no es mas que todos
los objetos contenidos en una clase son pasados en el constructor y no
construidos por la misma.
Esto permite que a la larga las clases queden muy desacopladas
permitiendo evolucionarlas con el menor impacto en el resto.



Este diseño me parece correcto, pero me desvia el problema de la
creacion de objetos a otra clase aparte.
Es decir yo en mi clase, se creo esos objetos, que solo se van a usar
en esa clase. Es decir no quiero que se creen en otro sitio, por nadie
mas, con lo que una factory no me vale, ya que cualquiera podria usarla
para crear esos objetos.

Resumiendo, yo quiero que sea la clase en concreto la que inicialice el
estado de la clase, que para eso está el constructor, no?

Para ir un poco mas yo sacaria un interfaz (por ejemplo ITipo) que
implementan tanto la clase tipoX como, evidentemente, la clase tipoY,
quedando el codigo como sigue:

class Ancestor
{
protected ITipo _objeto;
public Ancestor(ITipo nuevo_objeto)
{
_objeto = nuevo_objeto:
}

}

class Base : Ancestor
{
public Base(ITipo nuevo_objeto) : base(nuevo_objeto)
{
}
}

Espero que todo esto te ayude

Por cierto, yo nunca delegaria en las clases heredadas la creacion del
estado inicial, por lo menos no en aquella parte que le corresponde a
la clase base.


Osea, que en mi opinion, virtualizar el constructor no
me parece una buena idea.



Tengo que meditar esto, a ver que problemas me puede dar. Lo que no me
convence es tener que pasar
el objeto ya creado al constructor, ya que basicamente uso el
constructor para la creacion de los objetos.


Un saludo

Roberto M. Oliva




Emi
Respuesta Responder a este mensaje
#9 Roberto M. Oliva
22/01/2007 - 11:50 | Informe spam
Hola Emiliano!

Este diseño me parece correcto, pero me desvia el problema de la
creacion de objetos a otra clase aparte.
Es decir yo en mi clase, se creo esos objetos, que solo se van a usar
en esa clase. Es decir no quiero que se creen en otro sitio, por nadie
mas, con lo que una factory no me vale, ya que cualquiera podria usarla
para crear esos objetos.




Sipe, no hay problema en hacerlo como tu dices. Lo unico que te comento
son notas que mejoran la escalabilidad futura del proyecto. Se ha
demostrado que pasando objetos mediante su interfaz creados previamente
a aquellas clases que los vayan a utilizar te garantiza un
desacoplamiento de las clases y te va a permitir hacer un proyecto mas
escalable y mas actualizable.

Lo que tu quieres hacer pasaria a construirse asi:

ITipo objeto = new tipoY();
Base objBase = new Base (objeto);

No creo que complique mucho el codigo. En cambio te vas a aencontrar
que, si no modificas el interfaz ITipo, vas a poder modificar todo lo
que te de la gana las clases tipoY y tipoX y no vas a tener que tocar
para nada el codigo de Ancestor y el codigo de Base.
Tambien te va a permitir testear las clase Base y Ancestor sin
necesitar para nada los objetos tipoX ni tipoY. Con esto consigues
aislar los problemas que te puedan dar las clases: Testeas una clase en
si misma por mucho que utilice otra clase diferente no se si me
explico.

Tengo que meditar esto, a ver que problemas me puede dar. Lo que no me
convence es tener que pasar
el objeto ya creado al constructor, ya que basicamente uso el
constructor para la creacion de los objetos.



A ver si me consigo expresar. La herencia te permite tener una clase de
un tipo y luego crear otra clase que expande las caracteristicas de ese
tipo. Si tienes una clase base que inicializa su estado quiere decir
que especifica el estado inicial de las clases heredadas de ese mismo
tipo. No creo que sea bueno que las clases hijas "tapen" ese estado
inicial. No quiero decir que no se pueda, al igual que lo que te he
comentado antes, es una cuestion de recomendacion no de imposicion.

Resumiendo, yo quiero que sea la clase en concreto la que inicialice el
estado de la clase, que para eso está el constructor, no?



En nuestro ejemplo se define que Ancestor establece que debe haber un
valor de ITipo al inicializar el objeto, por eso solo existe ese
constructor y por eso el constructor lo primero que hace es
inicializarlo. A partir de aqui todas las clases heredadas no se tiene
porque preocupar de inicializar ese valor, porque esta impuesto por la
clase base. Efectivamente el constructor define el estado inicial, pero
no tiene porque crearse ese estado dentro del constructor, sino que
puede inicializase en base a parametros pasados.

Espero que todo esto te ayude... y no te lie ;) ... en todo caso aqui
estamos!!
Un saludo
Roberto M. Oliva
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida