Uso de Java [Interfaces / Clases abstractas] [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Últimamente decidí echar un vistazo a Java, así que todavía soy bastante nuevo en él y también en el enfoque de la programación OO, así que quería aclarar algunas cosas antes de aprender más, (supongo que nunca es pronto para comenzar con buena practicar).

Estoy programando un pequeño juego 2D por ahora, pero creo que mi pregunta se aplica a cualquier proyecto no trivial. Para la simplicidad voy a proporcionar ejemplos de mi juego.

Tengo diferentes tipos de zombies, pero todos tienen los mismos atributos (x, y, salud, ataque, etc.) así que escribí un interfaz Zombie que implemento WalkingZombie, RunningZombie TeleportingZombie, etc. ¿Es esto lo mejor que se puede hacer? ¿Soy mejor con una clase abstracta ? O con a super clase ? (No estoy planeando implementar parcialmente funciones-por lo tanto mi elección para una interfaz en lugar de una clase abstracta )

Tengo una clase que describe al personaje principal (Survivor) y como es bastante grande quería escribir una interfaz con las diferentes funciones, para que pueda ver y compartir fácilmente la estructura de la misma. Es una buena práctica? ¿O es simplemente una pérdida de espacio y tiempo?

Espero que esta pregunta no se califique como subjetivo porque pensé que los programadores experimentados no estarán en desacuerdo sobre este tipo de tema, ya que el uso de interfaces / super clases / clases abstractas sigue reglas lógicas y, por lo tanto, no es simplemente una elección personal.

Author: John Saunders, 2010-05-20

9 answers

Puedes pensar en una interfaz como un "contrato". Está definiendo un conjunto de métodos que las clases que implementan esta interfaz deben implementar.

Una clase abstracta, por otro lado, se usa cuando se tiene algún código que podría ser común a todas las clases secundarias que se quieren implementar. Por lo que podría tener una clase abstracta llamada Forma que tiene algún código común, y en sus clases derivadas (Círculo, Cuadrado, etc.) podría tener el código que es específico para esas formas (getArea sería ejemplo). Pero algo como el color podría ser común a todas las formas, por lo que podría poner un método getColor en su clase abstracta de Forma.

Y puedes combinar las dos ideas. Puede tener clases abstractas que implementan interfaces, y esto le da lo mejor de ambos mundos.

Estos conceptos se usan una y otra vez en OO, por lo que es importante entenderlos. Usted parece estar bien en su manera :).

Así que si su clase zombie tiene algún comportamiento común que se aplica a todos tipos de zombies, suena como un buen candidato para ser una clase abstracta. También podrías considerar crear una interfaz (tal vez una interfaz GameCharacter) si tienes otros personajes en tu juego (tal vez UndeadMice o algo así :)). Entonces su clase abstracta Zombie y la clase abstracta UndeadMouse implementarían la interfaz GameCharacter.

 15
Author: dcp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 20:54:33

Cuando tengo dudas, elijo seguir el paradigma GOF.

Encapsular lo que varía: - Definir un comportamiento único en su propia clase. Para hacer referencia al ejemplo anterior, implementa comportamientos para caminar, correr y teletransportarse en su clase separada. De esta manera, se implementa el comportamiento polimórfico.

Por el contrario, **Aggregate what is common** - Use clases abstractas para definir el comportamiento común en asociaciones polimórficas. Uso estos principios al diseñar relaciones entre objeto.

 4
Author: Kartik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 21:44:19

Sí, creo que estás yendo por el camino correcto con interfaces sobre clases abstractas.

Cualquier Zombi concreto que quieras hacer podría poseer cualquier combinación de las características de Caminar, Correr o Teletransportarse que quieras implementar.

Creo que la teoría de la programación moderna desalienta la herencia tanto como sea posible, porque inhibe la reutilización y la flexibilidad a largo plazo. Más bien, utilice interfaces y composición para lograr flexibilidad sin ' apretado acoplamiento'.

Una metodología para reutilizar código sin herencia, podría aplicar el paradigma de 'Favorecer la composición sobre la herencia'.

Me gusta pensar que 'Effective Java' (2nd edition) de Josh Bloch puede tomarse como "pensamiento actual" ...

Http://books.google.com/books?id=ZZOiqZQIbRMC&pg=RA1-PA71&lpg=RA1-PA71&dq=%22Bloch%22+%22Effective+java:+programming+language+guide%22+&hl=de&sig=RxlDlRBWUvNAzsAFzqOcftrYI5E#v=onepage&q&f=false

Por lo tanto, usted podría implemente todos sus comportamientos como clases independientes, y luego dé a cada implementación zombie su propia combinación de comportamientos, a través de la implementación y la composición..

Espero que eso tenga sentido y ayude ...

 3
Author: laher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-20 03:01:14

Habría escrito Zombie como una clase abstracta para evitar la redefinición de los campos x, y, salud, etc...

Para la clase Survivor, simplemente tendría que declarar públicas las funciones que se usarán externamente. Declaro funciones públicas en la parte superior de la clase. Declarar una interfaz cuando solo hay una clase implementándola inútilmente añade un archivo a mantener. Evítalo.

 1
Author: Maurice Perry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 20:52:52

Nadie está de acuerdo sobre el uso de interfaces sobre clases super/abstractas;)

La razón principal para usar interfaces y clases super/abstractas es habilitar el polimorfismo. En tu caso, por ejemplo, tienes cosas que se mueven en la pantalla (el jugador y los zombies, etc.). ¿Por qué no hacer que todos se muevan en la pantalla usando el mismo método? Tal vez heredar todo lo que se va a mover en la pantalla de un objeto llamado "Móvil" o algo así.

Y si realmente eres en este material es posible que desee mirar mixins también. No es algo que Java soporta directamente, pero hay bibliotecas construidas para ello.

 1
Author: JHollanti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 20:54:53

Tengo diferentes tipos de zombies, pero todos tienen los mismos atributos (x, y, salud, ataque, etc.) así que escribí un Zombie interfaz que implemento por WalkingZombie, RunningZombie teletransportingzombie etc. ¿Es esto lo mejor que se puede hacer? Soy mejor que con un clase abstracta? ¿O con una súper clase?

Una clase abstracta será una súper clase para tus zombis. una interfaz también sería en cierto sentido una super clase (super interfaz?) para su zombis.

Las propiedades comunes sugieren al menos una clase base abstracta para propiedades comunes.

(No estoy planeando implementar parcialmente funciones - por lo tanto, mi elección para una interfaz en lugar de una clase abstracta)

No estoy seguro de lo que quieres decir con esto.

Si tuvieras diferentes tipos de monstruos (duendes, orcos, etc.) puede encontrar un comportamiento común a estos que querrían pertenecer a diferentes clases base. esto sugeriría una interfaz.

Comenzaría con una clase base abstracta y vería lo que el código le dice mientras la escribe.

Tengo una clase describiendo al personaje principal (Survivor) y como es bastante grande quería escribir una interfaz con las diferentes funciones, para que pueda ver fácilmente y comparte la estructura de la misma. Es una buena práctica? O es simplemente un desperdicio de espacio y tiempo?

Su sobreviviente es lo que se llama un jugador-personaje (a diferencia de un personaje no jugador: alguien en un juego que normalmente no atacará a tu sobreviviente).

La mayoría de los juegos tratan a todos estos tipos de personajes como una especie de monstruo, ya que todos tendrán muchas propiedades en común (salud. magia, tesoros, armas, etc.)

Así que tal vez eso sea más un argumento para una interfaz.

Véase:

Usando la herencia y el polimorfismo para resolver un problema común del juego Ejemplos de diagrama de clases para RPG (Juego de roles Juego) diseñar la jerarquía de clases para los personajes típicos en el juego de rol

 1
Author: Ray Tayek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:13:27

No creo que en tu caso tu interfaz y estructura de clases se alineen bien con la realidad. De hecho, creo (corrígeme si me equivoco) que cada zombi puede caminar, correr, teletransportarse, etc. dependiendo de dónde esté.

Por lo tanto, debe tener una clase o interfaz zombi y tener acciones que modifiquen el estado del zombi. La acción probablemente sería una interfaz o una clase abstracta, por lo que puede aplicar cualquier acción a un zombi sin saber cuál es la acción exacta does (e. g. action.perform(zobie)).

Si tienes diferentes tipos de zombis, como zombis de tres patas y zombis de un solo brazo, es posible que desees implementar diferentes clases que manejen las cosas de zombis, como mostrarse a sí mismos o validar cambios de estado (por ejemplo, un tipo especial de zombi puede no aceptar ser teletransportado).

 0
Author: Lucero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 20:47:13

En términos de tu ejemplo de Zombi, la interfaz funcionará bien, a menos que tengas un código común que quieras que hagan todos los zombis.

Digamos que tienes un método Move, que hace que los walkingzombies caminen, runningzombies corran, etc. Sin embargo, si quieres "Mover" para hacer que cualquier tipo de zombie haga algo común, entonces la interfaz te obligará a duplicar código, ya que no puedes poner un cuerpo en una interfaz.

 0
Author: Greg Olmstead,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 20:50:51

Mi opinión es que es mejor usar la clase abstracta llamada Creature como una súper clase para todo tipo de, bueno, criaturas, y extenderla a Zombie para todo tipo de zombies.
Y también necesitará una interfaz.. para definir cuáles son las cosas que una criatura puede hacer..
como tal vez, caminar, o garra, o gritar...
la razón por la que necesitas una clase abstracta es desactivar la instanciación de Criatura , no querrías tener una criatura sin saber qué criatura lo es, ¿verdad?

 0
Author: p01ntbl4nk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-20 02:10:47