Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema Sublases En Java

Iniciado por Zeigon, 10 de Febrero de 2005, 02:07:46 PM

« anterior - próximo »

Zeigon

 pues a ver, tengo un problema con la ligadura dinámica entre clases, porque necesito que una superclase "actúe" como subclase para poder usar los métodos de ésta. me explico más:

tengo una clase abstracta A y una clase B que hereda de A:

public abstract class A
{
//lo que sea
}

public class B extends A
{
public void hola() {}
}

Entonces en otra clase, pongamos C, tengo un array de objetos de A, para si heredo más veces de A, pues que me valga para todas las subclases que haya. El problema se me plantea en que cuando quiera usar métodos o atributos de una subclase de A, por ejemplo B, no voy a poder hacerlo, ya que el array que tengo, es de objetos A, por lo que estos no conocen los métodos de su tipo dinámico o derivado, sólo verán los propios de A. así q de acceder al "hola()" de B, me olvido.

El sacar el tipo de subclase con los métodos (objeto.getClass().getName()) sería una solución, pero yo veo un poco chapuza el hacer 420 if por cada subclase que pueda tener. Aunque en realidad solo tendría 6 clases en lo que es este programa (que es un ajedrez y sólo hay 6 piezas), ya busco un método que sea de, digamos, buena programación, para poder hacerlo, si es posible, sin las ayudas del lenguaje, como puedan ser los métodos de antes "objeto.getClass().getName()", es decir por programación orientada a objetos y con 2 coj*** a ver si ya sale de una vez.

Si ayuda, puedo poner lo q es la estructura real (de mi ejemplo) de las clases si no se ve claro.

gracias.
eigon
----------------------------------------------
El arca de Noe fue construida por amateurs.
El Titanic por profesionales.

[Over]

 Hola.

Quizas no me he entrado bien, pero aunque tenga un array de clases A, puedes crear objetos B y meterlos en el array. Ya que B es hijo de A.

Asi, teniendo el array puedes coger el objeto del array y castear a clase B y asi accedes a las funciones especificas de B:

((ClaseB) claseC->arrayobjetosA[0]).functionDeClaseB();

Y logicamente desde B puedes acceder a A.

Releyendo tu post, si es para ajedrez supongo que cada tipo de ficha será una clase.

Puedes meter en A una variable que indique el "tipo de ficha" y que cada subclase meta el dato del tipo.

Cuando quieras acceder al objeto del array, miras el tipo de dato y casteas a la clase correspondiente.

PD: Creo que lo he dicho ya lo sabes...

Warchief

 La forma mala como dices es con instanceof (operador)

if(iterador.elementAt(i) instanceof claseA1) {
 iterador.elementAt(i).metodoA1();
} else if(iterador.elementAt(i) instanceof claseA2) {
 iterador.elementAt(i).metodoA2();
}


Hay un patrón para evitar eso. Creo que es el AbstractFactory.

Voy a echar un vistazo y ahora me retracto si estoy equivocado.

(de hecho creo que no es AF, ¿dónde está el designpatterns cuando se le necesita? (nooo) )

Warchief

 Nada, me he estado mirando los patrones y no he sacado nada en claro, nada más que creo que me refería al FactoryMethod y no al AbstractFactory. Mira a ver si puedes cambiar el diseño para utilizar alguno. Así que vea "factibles":
- Abstract factory (creación)
- Factory method (creación)
- Iterator (estructural)

Pero estoy un poco obcecado creo yo.

Patrones en:
http://www2.ing.puc.cl/~jnavon/IIC2142/guerrero.html



  • Al código del mensaje anterior le falta el cast explícito.
  • Iteradores donde siguiente() devuelve el siguiente elemento del array perteneciente a una determinada clase, me parece una idea factible (tampoco sé como tienes el diseño).

Zeigon

 debe ser q me explico mal pq en otro sitio tb han dicho q no me entendían mucho :P

el caso. yo lo intento reexplicar ahora con ejemplos concretos de mi programa:

clase A = clase Pieza
clase B = clase Alfil (caballo, torre... la q sea del ajedrez)
clase C = clase Ajedrez (la principal del juego, por llamarla de alguna forma, q crea el array de A).

entonces B hereda de A, por loq B puede ver lo de A, eso todo claro. El caso está en q yo tengo en cAjedrez un array de A (A[][]) q representa el tablero (no es exactamente así pero por no entrar en más detalles del programa). Entonces yo por ejemplo quiero hacer un movimiento y quiero llamar al método mover() de B, pero claro tenemos el array de tipo A. Podríamos hacer un casting perfectamente, pq total, en el ajedrez sólo hay 6 piezas diferentes así q no sería problema, pero ya q estamos para hacerlo bien, pues quería ver si habría alguna forma para hacerlo para cualquier clase, quiero decir, si tuviéramos en vez de 6, pues 20 clases, no quedaría bien hacer un casting por cada una de ellas pq nos saldrían chorrocientos If Else, y no es plan.

Por eso digo lo de algún método para no hacerlo así, aunq sea creando un array de otro tipo o algo así.

espero haberme explicado  :unsure:

creo q al final, por falta de tiempo, más q nada,  q tengo q entregar el trabajo este, me haré los 6 casting y tirando... aunq sigue en pie, ta claro lo de proponer una solución :P
eigon
----------------------------------------------
El arca de Noe fue construida por amateurs.
El Titanic por profesionales.

sés

 Hombre, pues el método mover() me parece bastante lógico que sea de la clase Pieza, que es común a todas las piezas, ¿no?

Me da la impresión de usas la clase Pieza simplemente para que la hereden el resto y poder meterlas en un vector (ses). En esa clase deberían estar todos los métodos comunes de las piezas.
Soy indeciso... ¿o no?

Warchief

 Claro (a lo q dice sés), yo me imaginaba algo así.

Los métodos que son comunes a todos van en la clase Pieza. Si tienen distinta implementación, cada subclase (alfil, caballo, torre...) sobreescribe el método con su implementación propia.

Si la clase Pieza no implementa nigún método puedes usar una Interface Pieza en vez de una clase abstracta.

Zeigon

 vale, ya sé lo q ha pasado, esto es lo que se llama un malentendido  (ole)

el caso es q tenía implementado el método mover() en la subclase, vamos en Alfil, y esas. pero no lo tenía definido como abstracto en Pieza y yo creía q sí, así q nada pues no me lo cogía, qn o existía q si tal q si cual.

así q nada, al final q lo tenía como tenía q estar, es decir, los métodos comunes en la clase base, y yo pensando, pero si lo tengo así, y claro he mirado ahora y me faltaba esa chorrada (nooo) .

gracias a todos  :D  
eigon
----------------------------------------------
El arca de Noe fue construida por amateurs.
El Titanic por profesionales.

Buffon

 bueno pues contesto yo por si acaso no se ha solucionado del todo.


Bienvenidos al fabuloso mundo del polimorfismo xdddd

si tienes una clase A que tenga definida una funcion mover abstracta. <---- ojo esto es necesario.

y luego tienes una clase B que tenga esa misma función implementada.

total kedaría

(CLASES DE A)        PIEZA
(CLASES DE B)        PEON  -  TORRE - CABALLO - ALFIL - REY - REINA

y tu en tu clase cAjedrez declaras un array de As, A[][]

como la función mover de A es abstracta, buscará la función de su hijo.

[CODE]
funcionIniciardeAjedrez()
{
  //A es un array de Piezas
  A[0][0] = new Torre();
  A[1][0] = new Caballo();
  ....

}

aki ahora, cuando tu hagas

A
  • [y].mover();

    se ejecutará la función del hijo, y no del padre, ya que la función mover de la clase Pieza es abstracta y en este caso estará buscando un hijo.

    Aunque te aviso, que dices que no es realmente así como lo estás haciendo, pero bueno, tener ese array polimórfico, para un juego de eventos no está mal, pero si el juego tubiera más acción no lo implementes así ;)

    era algo así lo que pedias?

    por que si no tampoco te entendido yo xddd

Buffon

 ostia no he leído tu ultimo mensaje sorry ya lo habias solucionado tu xdddd

Zeigon

 lo de q digo q no lo había hecho así no es q lo tenga de otra manera sin usar polimorfismo, lo q me refiero es q para simplificar el ejemplo y no meterme en cosas más concretas del programa, q la verdad, no creo q interesen, pues he puesto, por ejemplo, un array de Piezas[][], cuando en realidad no lo tengo así, y ya q estoy lo explico :P .
yo lo q tengo es un array de Casillas[][] q es otra clase que no había mencionado todavía, y  cada casilla tiene un objeto Pieza, y ya de ahí si saco el usar los métodos abstractos, accediendo a Casilla
  • [y].getPieza().mover(). y nada q así me ha quedado.

    gracis otra vez  (ole)  
eigon
----------------------------------------------
El arca de Noe fue construida por amateurs.
El Titanic por profesionales.

Buffon

 eso se llama facilidad a la hora de programar, ineficiencia a la hora de funcionar.

pero como te dicho, para un juego que depende de ciertos eventos que son lentos de cojones, pues no está mal, tipo ajedrez, o cualquiera de tablero, está de puta madre por que a la hora de corregir errores es mucho más "sencillo".






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.