Foro especializado en Warcraft III y su editor
 
BuscarEntrar al ChatboxPortal del foroÍndiceSpellsRegistrarseConectarseGrupos de Usuarios
Eventos Actuales
¡ Bienvenido Invitado !

Editar Perfil

Tus temas
Tus Mensajes ()

Enlaces rápidos








Comparte | .
 

 [Intermedio] Structs •

Ver el tema anterior Ver el tema siguiente Ir abajo 
AutorMensaje
Ruke

avatar


Barra de Salud : Su salud está al 100% - Este usuario no ha recibido infracciones

Mensajes Mensajes : 298
Reputación Reputación : 63
Monedas de oro : 1677
Monedas de Platino : 0

Inventario :



Mensaje(#) Tema: [Intermedio] Structs • Dom Ago 18, 2013 11:34 pm


Structs


Agregados en vJASS, los structs (cuando son correctamente utilizados) nos facilitan mucho la vida. No hay nada que no podamos hacer sin ellos (es opcional aprenderlos) pero si nos ayudan a organizar  y a hacer mas legible nuestro código (esto es MUY importante).



Índice




Comenzando Volver al índice


Los structs nos permiten pensar en objetos. Pensemos por un momento, en una persona. Sabemos que esa persona tiene un nombre, una edad, color de cabello y demás atributos que lo definen. Además sabemos que puede realizar ciertas  acciones, como caminar, hablar, y demás tipo de funciones.



¿Cómo pasaríamos esto a un struct?


Primero que nada, debemos definir nuestro struct Persona:



[jass]struct Persona

endstruct[/jass]

Atributos Volver al índice


Dijimos que la persona tenía atributos como su nombre, edad, etc.



[jass]struct Persona
   string nombre
   integer edad
endstruct[/jass]

Acciones/funciones/métodos Volver al índice


Y por último mencionamos que poseía ciertas acciones (caminar, hablar, y demás):



[jass]struct Persona
   string nombre
   integer edad
   
   method caminar takes nothing returns nothing
   
   endmethod
   
   method hablar takes nothing returns nothing
   
   endmethod
endstruct[/jass]

Nota: [ljass]method[/ljass] es "lo mismo" que decir [ljass]function[/ljass].

Instanciando Volver al índice


Ahora bien, tenemos el "molde" de una persona, vamos a crear (instanciar) una en si:



[ljass]Persona franco = Persona.create()[/ljass]

Ya tenemos a una persona. Nótese cómo en lugar de poner [ljass]integer[/ljass],  [ljass]string[/ljass], [ljass]real[/ljass] o cualquier otro tipo de variable, colocamos Persona.



Ahora que tenemos nuestra persona, vamos a darle un nombre y edad:



[jass]set franco.nombre = "Franco"
set franco.edad = 19[/jass]

Ahora digamos que quiero crear otra persona:



[jass]Persona maria = Persona.create()

set maria.nombre = "Maria"
set maria.edad = 21[/jass]

Llamando a los métodos Volver al índice


Ya jugamos con los atributos, vimos cómo asignarles valor. Ahora vamos a ver cómo llamar a sus funciones/acciones.



Anteriormente, habíamos creado dos métodos, los cuales eran caminar y hablar, pero ninguno de ellos hacía nada, así que vamos a modificar eso:



[jass]struct Persona
   string nombre
   integer edad
   
   method caminar takes nothing returns nothing
       call BJDebugMsg("está caminando")
   endmethod
   
   method hablar takes nothing returns nothing
       call BJDebugMsg("está hablando")
   endmethod
endstruct[/jass]

Ahora vamos a hacer que la persona "franco" camine, y que la persona "maria" hable:

[jass]Persona franco = Persona.create()
Persona maria = Persona.create()

set franco.nombre = "Franco"
set franco.edad = 19

@franco.caminar()@

set maria.nombre = "Maria"
set maria.edad = ?

@maria.hablar()@[/jass]

Si probamos esto, simplemente salen dos mensajes ("está caminando" y "está hablando"). Pero esto es aburrido, ¿no sería bueno que diga además, quién está caminando o quién está hablando?. Vamos a modificarlo para que tenga ese comportamiento:



[jass]struct Persona
   string nombre
   integer edad
   
   method caminar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está caminando")
   endmethod
   
   method hablar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está hablando")
   endmethod
endstruct[/jass]

Probamos, y efectivamente obtenemos: "Franco está caminando" y "Maria está hablando". Funciona tal y como lo habíamos planeado, pero qué es [ljass]this[/ljass].



Haciendo uso de this Volver al índice


[ljass]this[/ljass] toma el valor de la instancia con la que estamos trabajando. Recordar que cada persona, es una instancia de Persona (valga la redundancia). Esto se podría traducir en lo siguiente:



Franco
[jass]    method caminar takes nothing returns nothing
       call BJDebugMsg(@franco@.nombre + " está caminando")
   endmethod[/jass]

Maria
[jass]method hablar takes nothing returns nothing
       call BJDebugMsg(@maria@.nombre + " está hablando")
   endmethod[/jass]

Visibilidad Volver al índice


En los ejemplos anteriores, vimos cómo modificar y obtener atributos... pero hay un problema, ¿acaso podemos modificar el nombre o la edad de una persona a voluntad?, por supuesto que no.


Muchas veces, nos encontraremos (o se encontrarán) con estos problemas, en los que no queremos que un valor pueda modificarse y obtenerse, o que no se pueda modificar pero si obtener o viceversa. Estas situaciones, se resuelven determinando la visibilidad.



Volviendo al struct Persona. Queremos que el atributo nombre solamente pueda asignarse una vez, lo mismo para el atributo edad. Para ello, vamos a tener que hacer varios cambios:



[jass]struct Persona
   @readonly@ string nombre
   @readonly@ integer edad
   
   method caminar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está caminando")
   endmethod
   
   method hablar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está hablando")
   endmethod
   
   static method create takes string nombre, integer edad returns Persona
       local Persona this = Persona.allocate()
       
       set this.nombre = nombre
       set this.edad = edad
       
       return this
   endmethod
endstruct[/jass]

[ljass]readonly[/ljass]: Se podría traducir a "solo leer". Esto quiere decir que si intentamos darle valor (como lo hicimos anteriormente) tendremos un error. Solo la podemos "leer"



[ljass]static method create[/ljass]: ¿Recuerdas que para instanciar (crear) una nueva persona, teníamos que hacer [ljass]Persona.create()[/ljass]?, como ahora hemos cambiado las cosas, para instanciar una nueva persona, debemos hacer [ljass]Persona.create(<nombre>, <edad>)[/ljass].



[ljass]local Persona this = Persona.allocate()[/ljass]: En esta línea, decimos que necesitamos crear una nueva instancia, por lo que nos devuelve una lista para usar.



[ljass]return this[/ljass]: Ya tenemos nuestra instancia, trabajamos con ella (asignando valores) y decimos que ya está lista para que se use, por lo que la "devolvemos".



¿Has notado el [ljass]static[/ljass] en el método [ljass]create[/ljass]?

[ljass]static[/ljass] no trabaja con instancias, trabaja con el "struct en si". Como anteriormente vimos, cuando llamábamos a [ljass]create[/ljass], lo hacíamos con [ljass]@Persona@.create()[/ljass]. Mas adelante lo vamos a estar viendo un poco mas a fondo.



Volviendo a lo que queríamos hacer, dijimos que tanto nombre como edad solamente se podrían asignar (darle valor) una sola vez. Con esto, ya lo hemos logrado.



Ahora, ¿qué pasa cuando tenemos un atributo que no queremos que se pueda obtener ni modificar?, para estos casos, se hace uso de [ljass]private[/ljass].



Supongamos que cada persona, tiene la contraseña de su cuenta bancaria. Este es un valor el cual no queremos revelar a otras personas y tampoco podemos modificarlo.



[jass]struct Persona
   readonly string nombre
   readonly integer edad
   
   @private string contraseña_bancaria@
   
   method caminar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está caminando")
   endmethod
   
   method hablar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está hablando")
   endmethod
   
   static method create takes string nombre, integer edad, @string contraseña_bancaria@ returns Persona
       local Persona this = Persona.allocate()
       
       set this.nombre = nombre
       set this.edad = edad
       @set this.contraseña_bancaria = contraseña_bancaria@
       
       return this
   endmethod
endstruct[/jass]

Si intentamos algo como:



[jass]set franco.contraseña_bancaria = "1234"
call BJDebugMsg(franco.contraseña_bancaria)[/jass]

Veremos que nos arroja un error.



Nota: El uso de "ñ" no es válido, solo es para el ejemplo.


La visibilidad puede asignarse tanto a atributos como a métodos.



Volviendo a static Volver al índice


Dijimos que static no utilizaba instancias, si no que trabaja con "el struct en si". Tanto los atributos como métodos estáticos, no son útiles para cuando tenemos un caso en donde no es necesario instanciar (por ejemplo, el atributo nombre no podría ser estático, puesto que no todas las personas tienen el mismo nombre).



Por ejemplo, supongamos que queremos tener un conteo de todas las personas que han sido creadas. Para ello, podemos crear un atributo estático cuyo valor sea, precisamente, la cantidad de personas que han sido creadas. Además, queremos saberlo, pero hay un detalle, ¡no debemos ser capaces de modificar ese valor!.



[jass]struct Persona
   @readonly static integer contador = 0@

   readonly string nombre
   readonly integer edad
   
   private string contraseña_bancaria
   
   static method mencionarCantidadDePersonas takes nothing returns nothing
       call BJDebugMsg("En total hay " + I2S(Persona.contador) + " personas")
   endmethod
   
   method caminar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está caminando")
   endmethod
   
   method hablar takes nothing returns nothing
       call BJDebugMsg(this.nombre + " está hablando")
   endmethod
   
   static method create takes string nombre, integer edad, string contraseña_bancaria returns Persona
       local Persona this = Persona.allocate()
       
       set this.nombre = nombre
       set this.edad = edad
       set this.contraseña_bancaria = contraseña_bancaria
       
       @set Persona.contador = Persona.contador + 1@
       
       return this
   endmethod
endstruct[/jass]

Nótese que en el método [ljass]create[/ljass] estamos aumentando en uno (1) el contador de personas, esto es porque, ¡acabamos de crear una persona!.



Ahora que hemos agregado el contador, podemos llevar el registro de la cantidad de personas que han sido creadas, y además:



[ljass]Persona.mencionarCantidadDePersonas()[/ljass]

Podemos crear un mensaje mencionando la cantidad de personas Wink.



Finalizando... Volver al índice


Si has llegado a esta parte de este breve tutorial, mis felicitaciones pues lo has completado Smile. Espero que se haya entendido y no haya sido muy complejo.


Ante cualquier duda, me comentan y solucionamos Wink.


Saludos.




Última edición por Sauron el Sáb Ago 24, 2013 6:50 pm, editado 3 veces
Volver arriba Ir abajo
Distor
Peón
avatar


Barra de Salud : Su salud está al 100% - Este usuario no ha recibido infracciones

Mensajes Mensajes : 41
Reputación Reputación : 9
Monedas de oro : 245


Inventario :



Mensaje(#) Tema: Re: [Intermedio] Structs • Dom Ago 18, 2013 11:56 pm

Sauron!! Sad gracias gracias maaaaan!
Prometo aprenderlo que bueno ver que estes acaaa Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy 
Volver arriba Ir abajo
Marcos_M

avatar


Barra de Salud : Su salud está al 100% - Este usuario no ha recibido infracciones

Mensajes Mensajes : 3105
Reputación Reputación : 520
Monedas de oro : 9620
Monedas de Platino : 0

Inventario :



Mensaje(#) Tema: Re: [Intermedio] Structs • Dom Ago 18, 2013 11:59 pm

Soy yo o la visualización está mal?
Volver arriba Ir abajo
WonderWoman
Capitán
avatar


Barra de Salud : Su salud está al 100% - Este usuario no ha recibido infracciones

Mensajes Mensajes : 129
Reputación Reputación : 27
Monedas de oro : 829
Monedas de Platino : 0

Inventario :



Mensaje(#) Tema: Re: [Intermedio] Structs • Dom Dic 22, 2013 12:08 am

Aguanten las tablas hash y el hash loco.


and it makes me wonder...
Volver arriba Ir abajo
Contenido patrocinado




Mensaje(#) Tema: Re: [Intermedio] Structs •

Volver arriba Ir abajo
 

[Intermedio] Structs •

Ver el tema anterior Ver el tema siguiente Volver arriba 
Página 1 de 1.

Permisos de este foro:No puedes responder a temas en este foro.
Warcraft III - WorldEditor :: Academia :: Area JASS-