post thumbnail

Objective-C desde Cero: Orientación a Objetos

Publicado Por: Oscar González, El 01/07/2013


Detalles del Curso:

Dificultad: Novato

Duración: 20 min


Más artículos en Objective-C desde Cero

Este es el artículo Orientación a Objetos de la serie Objective-C desde Cero - Mostrar todos

  1. Conceptos Básicos
  2. Orientación a Objetos
  3. Orientación a Objetos - parte 2
  4. Strings, Números y Colecciones

En este capítulo de Objective-C desde Cero hablaremos de como este lenguaje implementa el paradigma orientado a objetos.


Clases

En Objective-C las clases son representadas mediante el uso de dos archivos, en lugar de uno como Java y C#, estos archivos son llamados encabezado e implementación, y llevan las extensiones .h y .m respectivamente.

¡Alerta!

Para esta demostración vamos a abrir Xcode y vamos crear un proyecto nuevo de tipo "Command Line Tool" exactamente igual al del capitulo anterior, esta vez yo lo voy a llamar "Ejemplo - Objetos". Si no sabes como hacerlo, revisa: Objective-C desde Cero - Conceptos Básicos

Una vez tengamos la ventana principal de Xcode con nuestro proyecto listo para desarrollase, vamos a crear una clase nueva. Hacemos click derecho en nuestra capeta principal del proyecto (option + click) y seleccionamos New File.

Imagen de menu New File Xcode

En el menú de plantillas seleccionamos Objective-C Class.

imagen de menú de plantillas de Xcode - selección: Objective-C Class

Llamamos a nuestra clase Person e indicamos que es una subclase de NSObject. En Objective-C, todas las clases heredan de NSObject, así como en java todas de Object.

Imagen de nombre de clase Person

Guardamos el archivo en la carpeta de nuestro proyecto, le damos a **Create* y veremos como aparece nuestra clase en el navegador de archivos. Vamos de una vez al archivo .h (encabezado).

Imagen de navegador de archivos con Person.h seleccionado

Debería contener lo siguiente:

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

En los archivos .h de las clases anunciamos los atributos y métodos que serán públicos.

Si vamos al .m (implementación), encontraremos el siguiente código:

#import "Person.h"

@implementation Person

@end

Todo lo que coloquemos en el .m de una clase y no esté declarado en el .h, será privado.


Apuntadores

Los apuntadores son variables que hacen referencia a objetos. Estudiemos la estructura de un apuntador. Vamos al archivo main.m e importamos nuestra clase Person (en cualquier lugar antes de la función main). Debe lucir así:

#import "Person.h"

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        // insert code here...
        NSLog(@"Hello, World!");

    }
    return 0;
}

Ahora borramos todo lo que esté dentro del bloque @autoreleasepool ya que no lo vamos a necesitar y agregamos el siguiente código:

Person *oscar = [[Person alloc] init];
  1. Person es nuestro tipo de dato, queremos guardar en la variable una referencia a un objeto de tipo Person.
  2. El "*" (asterisco) indica que esta variable es un puntero.
  3. Ahora nos topamos con [[Person alloc] init]. Con esto creamos una instancia de la clase person. "alloc" reserva un espacio en memoria para la variable. Una vez tengamos esta instancia le decimos "init", este es el constructor por defecto de todas las clases en Objective-C. Este bloque de código podría ser reemplazado por [Person new], esto es el equivalente a hacer [[Person alloc] init]. Cualquiera de los dos es válido y generan el mismo resultado, sin embargo yo prefiero seguir haciendo alloc e init ya que init puede ser sobrescrito o sobrecargado para recibir parámetros.

El archivo main.m debe lucir así ahora:

#import "Person.h"

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Person *oscar = [[Person alloc] init];

    }
    return 0;
}

Mensajes

En Objective-C, a los métodos de las clases se les llama Mensajes, ya veremos porqué. Sin embargo yo sigo llamándolos métodos, es por costumbre, Objective-C no fue el primer lenguaje que aprendí.

Vamos a agregar cuatro métodos al encabezado de nuestra clase Person.

  • El primero será walk (caminar)
- (void)walk;

Revisemos la estructura del metodo:

  1. Primero nos encontramos con el carácter "-" (guión). Esto indica que el método es de instancia, es decir, para poder llamarlo debes hacerlo a través de un objeto instancia de la clase. Si quisiéramos hacer que el método fuera estático, entonces deberíamos cambiar el "-" por "+" (más)
  2. Tenemos ahora "(void)". Esto significa que nuestro método el un procedimiento, no una función, entonces no va a retornar ningún valor.
  3. Por último está "walk", este es el nombre del método.
  • Seguimos con saltar y le pasamos una altura:
- (void)jumpHeight:(float)centimeters;
  1. Aquí todo es similar hasta que llegamos a los dos puntos ":", estos indican que viene un parámetro.
  2. "(float)", este es el tipo de dato del parametro entre paréntesis.
  3. "centimeters" es el nombre del parametro.
  • Ahora correr una distancia con una velocidad:
- (void)runDistance:(float)meters withSpeed:(float)speed;
  1. Este método recibe dos parámetros: centimeters y speed; ambos de tipo float. El nombre completo del método es "runDistance:withSpeed:", y aquí es donde muchos se confunden, en Objective-C los nombres de los métodos deberían anunciar o dar una idea de que tipo son los parámetros que reciben, por eso "runDistance:{parámetro distancia} withSpeed:{parámetro velocidad}". Esto una genialidad, ya que el código se hace más "mantenible" al facilitar la identificación de los parámetros que reciben los métodos, y esto se hace más evidente cuando llamamos a los métodos, ya vamos a ver.
  • Por último agregaremos el método estático "edad":
+ (int)age;
  1. En este caso vemos que empieza con "+" porque es un método estático (puede ser invocado sin hacer una instancia de la clase).
  2. "(int)" es el tipo de dato que retorna, esto nos hace darnos cuenta que este método es una función y que retorna un int
  3. El nombre del método es age. (La edad normalmente debería ser un método de instancia, pero para efectos de esta demostración lo vamos a dejar estático)

Nuestro encabezado debería verse así:

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (void)walk;
- (void)jumpHeight:(float)centimeters;
- (void)runDistance:(float)meters withSpeed:(float)speed;
+ (int)age;

@end

Ahora en el archivo de implementación (.m) vamos a escribir lo que hacen cada unos de estos métodos.

- (void)walk
{
    NSLog(@"Caminando");
}

En walk vamos a imprimir por consola "Caminando". Los string en Objective-C se declaran empezando por "@" y luego entre comillas el mensaje.

- (void)jumpHeight:(float)centimeters
{
    NSLog(@"Saltando %f centímetros", centimeters);
}

En el mensaje vamos a incluir la altura que le pasamos. %f será reemplazado por el valor de tipo float que le pasamos.

- (void)runDistance:(float)meters withSpeed:(float)speed
{
    NSLog(@"Corriendo %f metros a %f m/h", meters, speed);
}

Aquí imprimimos los dos parámetros.

+(int)age
{
int myAge = 24

NSLog(@"mi edad es %i años", myAge);

return myAge;
}

En este imprimimos un simple mensaje de solo texto.

Person.m debería lucir de la siguiente manera:

#import "Person.h"

@implementation Person

- (void)walk
{
    NSLog(@"Caminando");
}


- (void)jumpHeight:(float)centimeters
{
    NSLog(@"Saltando %f centímetros", centimeters);
}


- (void)runDistance:(float)meters withSpeed:(float)speed
{
    NSLog(@"Corriendo %f metros a %f m/h", meters, speed);
}


+ (int)age
{
int myAge = 24

NSLog(@"mi edad es %i años", myAge);

return myAge;
}

@end

Ahora vamos a main.m a llamar a estos metodos, Esto lo hacemos de la siguiente manera:

[oscar walk];

[oscar jumpHeight:107.3f];

[oscar runDistance:10.5f withSpeed:8.0f];

[Person age];

¿Ahora ves por qué se llaman mensajes?, es como si le hablaras a la clase/objeto para que haga algo.

  1. Los métodos de instancia los llamamos a través del objeto (tres primeras invocaciones). oscar, camina, salta, corre, etc,
  2. Los métodos estaticos se llamar a través de la clase (cuarta invocación).
  3. ¿Por qué hay una "f" después de los números con decimales?. Así es como se expresan en Objective-C.

El archivo main.m debe lucir de la siguiente manera:

#import "Person.h"

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Person *oscar = [[Person alloc] init];

        [oscar walk];

        [oscar jumpHeight:107.3f];

        [oscar runDistance:10.5f withSpeed:8.0f];

        [Person age];

    }
    return 0;
}

Si corremos este programa en Xcode, debería imprimir lo siguiente en la consola:

Caminando
Saltando 107.300003 centímetros
Corriendo 10.500000 metros a 8.000000 m/h
Mi edad es 25 años

Conclusión

En este capítulo aprendimos a escribir clases, agregarle métodos, pasarle mensajes a objetos, hacer instancias de clases y a crear punteros.

En el próximo vamos a hablar de atributos, las clases más utilizadas del framework Foundation de Apple y como Objective-C maneja la memoria.

Si tienes dudas o preguntas no dejes de exponerlas en los comentarios.

¡Nos vemos!


¿Te ha gustado esta publicación?

Compártela:

Por Oscar González

Conoce más sobre este autor aquí


comments powered by Disqus