Curso básico de Objective C: Clases y Objetos
Primeros Pasos
Como buen lenguaje de programación orientado a objetos Objective C permite el uso de clases en el código. A continuación veremos varios ejemplos de uso de las Clases.
Empecemos por dar de alta una clase en Xcode en un proyecto cualquiera. Para ello deberemos pulsar Comando + N para un crear un nuevo fichero, a continuación aparecerá el siguiente diálogo:
En la parte izquierda podemos ver los distintos tipos de ficheros que podemos crear. Seleccionaremos Cocoa o Cocoa touch dependiendo de si estamos haciendo una aplicación para Mac OSX o para iOS y pulsamos en Next, a continuación nos preguntará por el nombre de la clase y su herencia:
Pondremos el nombre de la clase en el campo Class e indicaremos en el selector, o escribiremos el nombre directamente, de la Clase Padre de la nueva clase que vamos a crear.
NSObject es la Clase principal del Objective C, aquellos que vengan de Java verás que es muy similar en concepto y métodos a los que nos encontramos en la clase Object.
Por lo tanto para empezar rellenaremos el nombre con “MiClase” y dejaremos en el selector “NSObject” por simplificar la primera clase.
Una vez rellenado este paso del asistente pulsamos en Next y nos saldrá el dialogo para indicar donde queremos guardar la nueva clase:
Seleccionaremos la carpeta donde se guardará la clase en la parte superior y en la inferior indicaremos el grupo, que es la manera que tiene de denominar Xcode las carpetas virtuales dentro del proyecto. Dentro de la carpeta del proyecto tenemos una carpeta con ese mismo nombre. y es donde se situará los ficheros de la clase.
El target o el destino de la clase, como puede verse en la captura 01_clases es el nombre del proyecto y el target de compilación y ejecución del mismo. Lo dejamos seleccionado y pulsamos en el botón Create.
Esto nos creará los ficheros en el proyecto y nos abrirá automáticamente el fichero de implementación “.m” en el editor, tal como puede verse en la captura:
También podemos ver cómo en la parte izquierda tenemos dos ficheros correspondientes a la nueva clase. El fichero .h o de cabecera (sí como en C) y el fichero .m de implementación.
Como derivado de C disponemos de los dos ficheros, uno para las definiciones y otro para la implementación.
Veamos el contenido del fichero .h
En este caso, a parte de los típicos comentarios explicatorios de la clase, tenemos un import
#import <Foundation/Foundation.h>
Que permite importar, como el C, un fichero de cabecera de una biblioteca de sistema, de ahí los <>, en este caso la biblioteca Fundation. Esta biblioteca es la que dispone de la mayor parte de las clases de objetos de Objective C por lo que deberemos importarla siempre.
En el fichero de cabecera, el .h, la clase se enmarca entre el @interface y el @end
Después del @interface se coloca el nombre de la clase, en este caso Miclase, seguido de un : y el nombre de la clase padre en este caso NSObject .
Por otra parte en el fichero .m, el de implementación nos encontramos con lo siguiente:
De la misma manera deberemos importar el fichero de cabecera de la clase:
Y la implementación estará enmarcada entre las anotaciones @implementation , seguido del nombre de la clase Miclase y terminando con el @end .
Objetos
Instanciación de Objetos
La definición de la función alloc es la siguiente:
– (id) alloc;
Se ejecuta el método de la clase alloc esta es la primer sorpresa en Objetive C. Para ejecutar métodos, que se denomina paso de mensajes en Objective C, se coloca el nombre de la clase un espacio y a continuación el nombre del método que se desea ejecutar, todo ello rodeado de los corchetes.
La declaración de la función init es la siguiente:
– (id) init;
Nota de codificación: Prueba a escribirlo de la siguiente manera:
- primero hay que declarar el objeto
- escribe el nombre de la clase, verás que Xcode te ayuda a rellenarlo, según vas pulsando se va acercando a la clase que buscas, cuando la tengas seleccionado, pulsa enter
- no te olvides de poner el * entre la clase y el nombre del objeto. Si no lo haces Xcode te saltará un aviso de que no lo has puesto y cómo arreglarlo, poniéndolo XD
- escribe el nombre de la variable del objeto
- luego escribe el =
- Luego pon un abre corchete [
- Escribe el nombre de la clase, verás que Xcode te ayudará a rellenarla y te aparecerá el corchete de cierre en un tono de gris, como si no estuviera escrito todavía pero que con un gesto podríamos ponerlo, esto se ve más adelante.
- pon un espacio y una a, verás que Xcode también completa los nombres de métodos
- selecciona alloc pulsando enter
- pulsa el botón derecho del teclado o el tabulador, verás como se escribe finalmente el cierra corchete, poniéndolo el color negro definitivo
- escribe in, verás que sale el método init
- pulsa enter y se escribirá el método completo
- escribe un cierra corchete y verás como justo delante del nombre de la clase
- pon el ; al final
Propiedades de Objetos
Inclusión de Atributos (propiedades)
Características de una propiedad (property attributes)
- getter: permite definir el nombre del método getter, de la siguiente manera: getter=nombreDeMetodo
- readwrite: por defecto las propiedades en Objective C son de lectura escritura.
- readonly: para aquellas propiedades que se tienen que comportar como de sólo lectura.
- copy: permite realizar una copia del objeto cada vez que se asigne a otra variable.
- nonatomic: todas las variables de Objetive C son atómicas, en el sentido de comunicación entre hilos de ejecución. Es decir, significa que dos hilos intentan realizar un incremento sobre una variable, no haría problema a la hora de sincronizar esos dos hilos para que en ella se puedan actualizar los valores. Si queremos que las variables no se comporten así las definiremos como nonatomic. Al no necesitar sincronizar los accesos a las variables el rendimiento de la aplicación mejor.
- strong: serán punteros responsables o poseedores de una variable. Por lo tanto si se elimina ese puntero y no hay otra variable strong sobre ese conjunto de datos, se procederá a una liberación automática de la memoria que ocupaba ese dato. Se solía llamar antes retain. Sólo funciona con objetos. Más información: Referencia de Apple.
- weak: es el caso contrario a strong, no pasa nada si se libera una variable weak. Se pueden llamar también punteros temporales.
Uso de propiedades de un objeto
Getters y Setters, paso de mensajes relacionados con una propiedad
De las misma manera que ejecutamos métodos de un objeto, o paso de mensajes en Objective C, ponemos el nombre del objeto, un espacio, set y el nombre de la propiedad un dos puntos para pasar un parámetro, ojo no flipes demasiado, y luego el valor o variable que le queremos pasar todo por supuesto rodeado de corchetes.
Funciona de una manera similar a un JavaBean, el nombre siempre es set en minúscula seguido del nombre de la variable con la primera letra mayúscula y el resto en minúsculas, CamelCase otra vez.
Todos los métodos en Objective C se escriben de esta manera, así son más fáciles de recordar y escribir.
Con el anterior ejemplo hemos colocado el valor 1 en la propiedad del objeto.
Veamos ahora el getter:
de esta manera ponemos entre corchetes el nombre del objeto, un espacio y el nombre de la propiedad.
A mi me sigue pareciendo más cómodo el uso del punto, pero para aquellas propiedades que sean privadas será más apropiado llamar al getter en su lugar.
La función nos devolverá el valor de la propiedad, otra diferencia con los JavaBeans. Aquí no se pone el get delante del nombre de la propiedad.
De esta manera para sacar por consola el valor almacenado en la propiedad pondremos lo siguiente:
Métodos de Clase
Inclusión de un método
Implementación
A continuación deberemos realizar la implementación del método en el fichero .m, de una manera similar a la siguiente:
La implementación del método es igual a la definición salvo por los {} que son los que incluirán el código que deberá ejecutar el método al ser invocado.
Haremos que por ejemplo escriba algo en la consola:
De esta manera el método completo quedará de la siguiente manera:
Invocación
Paso de Parámetros
Acceso a propiedades desde la implementación de la clase
Resumen de código
Invocación del método con un parámetro
Devolviendo valores
Varios parámetros devolviendo un valor
Metodos estáticos
Para definir un método estático, se diferencia por el uso del + antes de la definición del método en vez del -, veamos un ejemplo, definido en el .h:
Ahora su implementación en el .m:
Un método sencillo 🙂
Ahora su invocación desde el main.m:
Como puede verse se utiliza el nombre de la clase en vez del nombre del objeto, al como ocurre con el método alloc.
Llamar a los métodos del padre (herencia)
Llamar a los métodos de la propia clase
En un determinado momento nos puede llegar a interesar llamar a un método hecho en la clase que estoy creando nueva, para ello deberemos usar lo siguiente:
[self nombreDelMetodo];
Contructores (init)
Si queremos inicializar las propiedades de un objeto cuando se iniciativa es necesario crear una implementación del método init en la clase.
Dentro del fichero de cabecera deberemos introducir lo siguiente:
– (id) init;
Una vez definida el método debemos realizar la implentación, en el fichero .m, de una manera similar a la siguiente:
– (id)init {
self = [super init];
if (self) {
//Aquí se inicializan las variables
propiedad=0;
}
return self;
}
Como puede verse en el ejemplo el método devuelve self es decir el mismo objeto. Es una buena práctica llamar al constructor del padre antes de nada y luego comprobar si el objeto se ha inicializado apropiadamente con un if. Si eso es así, dentro del código del if, introducimos las inicializaciones pertinentes.
Dentro del fichero de cabecera deberemos introducir lo siguiente:
Como puede verse en el ejemplo el método devuelve self es decir el mismo objeto. Es una buena práctica llamar al constructor del padre antes de nada y luego comprobar si el objeto se ha inicializado apropiadamente con un if. Si eso es así, dentro del código del if, introducimos las inicializaciones pertinentes.
Contructores con parámetros (initWith)
Para poder llamar a ese contractos en el main.m pondríamos algo similar a esto:
Otras maneras de inicializar propiedades
De esta manera conseguimos que cada vez que se va a acceder a dicha propiedad se inicialice el objeto en el caso de que no haya sido inicializado previamente.
Visibilidad de métodos y propiedades
Resumen
Ejercicios propuestos
- Crea un nuevo proyecto
- Crea una nueva Clase llamada MiClase
- Declara un objeto de la clase MiClase en el main.m
- Inicializa dicho objeto.
- Incluye una propiedad en la clase
- Utiliza esa propiedad desde el main.m
- Crea un método nuevo al que no le pases ningún parámetro ni devuelva nada en la clase
- Invoca ese nuevo método desde el main.m
- Crea un método nuevo al que le pases un parámetro pero no devuelva nada en la clase
- Invoca ese nuevo método desde el main.m
- Crea un método nuevo que haga la suma de dos números y devuelva el resultado
- Invoca ese nuevo método desde el main.m
- Crea una clase Cliente: con los siguientes datos: código de cliente, nombre, tlf y dirección.
- Inicializa un objeto de tipo Cliente en el main.m
- Crea un constructor con parámetros y sin parámetros para la clase Cliente
- Utiliza el constructor con parámetros para inicializar un objeto de la clase Cliente en el main.m
Comments