OOP ObjC

52
Programação Orientada a Objectos (OOP) - Parte 2: ObjC Jorge C. S. Cardoso, Luís Gustavo Martins [email protected], [email protected] Cursos de Verão na Católica 2010

description

Slides do segundo dia do Workshop (intensivo :) ) sobre Introdução à Programação de Dispositivos Móveis (Google Android, Apple iPhone, iPod Touch e iPad)

Transcript of OOP ObjC

Page 1: OOP ObjC

Programação Orientada a Objectos (OOP) - Parte 2: ObjC

Jorge C. S. Cardoso, Luís Gustavo [email protected], [email protected]

Cursos de Verão na Católica 2010

Page 2: OOP ObjC

Classe Veículo em ObjCDivisão do código em duas partes:

1.Interface declarada num ficheiro Veiculo.h

2.Implementação definida num ficheiro Veiculo.m

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 3: OOP ObjC

Classe Veículo em ObjCInterface - Veiculo.h

O ObjC "obriga" ao uso de getters e setters

    --> Encapsulamento!

#import <Foundation/Foundation.h>

@interface Veiculo : NSObject {    // instance variables     int velMax;    int velActual;    int numRodas;    int numLugares;}//setters and getters- (void) setVelMax: (int)vel;- (int)  velMax;- (void) setVelActual: (int)vel;- (int)  velActual;- (void) setNumRodas: (int)numRodas;- (int)  numRodas;- (void) setNumLugares: (int)numLugares;- (int)  numLugares;// other method declarations- (void) arrancar;- (void) travar;- (void) acelerar;- (void) buzinar;- (BOOL) estaParado;- (void) mostrarEstado;@end

Page 4: OOP ObjC

Classe Veículo em ObjCImplementação - Veiculo.m#import "Veiculo.h"

@implementation Veiculo 

//setter and getters-(int)velMax {    return velMax;}-(void) setVelMax: (int)vel {    velMax = vel;}//... similar for other setter/getters

//other methods-(void) arrancar {    //implementação do método arrancar...}

-(void) travar {    // ...}

//... other methods...

@end

• Implementar setters/getters• Implementar métodos

Getters e setters podem ser criados automaticamente...    - properties    - synthesize

Page 5: OOP ObjC

Classe Veículo em ObjCUso de Properties e Synthesized Getters e Setters

#import <Foundation/Foundation.h>

@interface Veiculo : NSObject {    // instance variables     int velMax;    int velActual;    int numRodas;    int numLugares;}//setters and getters- (void) setVelMax: (int)vel;- (int)  velMax;- (void) setVelActual: (int)vel;- (int)  velActual;- (void) setNumRodas: (int)numRodas;- (int)  numRodas;- (void) setNumLugares: (int)numLugares;- (int)  numLugares;// other method declarations- (void) arrancar;- (void) travar;- (void) acelerar;- (void) buzinar;- (BOOL) estaParado;- (void) mostrarEstado;@end

#import <Foundation/Foundation.h>

@interface Veiculo : NSObject {    // instance variables     int velMax;    int velActual;    int numRodas;    int numLugares;}//properties@property velMax;@property velActual;@property numRodas, numLugares;

// other method declarations- (void) arrancar;- (void) travar;- (void) acelerar;- (void) buzinar;- (BOOL) estaParado;- (void) mostrarEstado;@end

Page 6: OOP ObjC

Classe Veículo em ObjCUso de Properties e Synthesized Getters e Setters

#import "Veiculo.h"

@implementation Veiculo 

//setter and getters-(int)velMax {    return velMax;}-(void) setVelMax: (int)vel {    velMax = vel;}//... similar for other setter/getters

//other methods-(void) arrancar {    //implementação do método arrancar...}

-(void) travar {    // ...}

//... other methods...

@end

#import "Veiculo.h"

@implementation Veiculo 

//synthesized setter and getters@synthesize velMax;@synthesize velActual:@synthesize numRodas;@synthesize numLugares;

//other methods-(void) arrancar {    //implementação do método arrancar...}

-(void) travar {    // ...}

//... other methods...

@end

Page 7: OOP ObjC

Classe Veículo em ObjCUso de Properties e Synthesized Getters e Setters

• É possível alterar o comportamento do setter sintetizado para uma variável membra, usando modificadores

Num setter do tipo:

    -(void) setVar: (SomeClass *)value

Se o sintetizarmos com os seguintes modificadores, teremos no corpo do setter (sintetizado) as seguintes atribuições:

    @property (assign) var 

    var = value; //simple assignation

  @property (retain) var        var = [value retain]; //assignation with reference counter increment

  @property (copy) var

    var = [value copy]; //object is copied (must conform to the NSCopying protocol...)

Page 8: OOP ObjC

Herança em ObjC

• O ObjC suporta herança simpleso ou seja, uma classe apenas pode herdar de uma classe pai

Tal como o Java (outras linguagens, como o C++, suportam herança múltipla)o Em vez de herança multipla, o ObjC suposta o uso de "categories" e

"protocols" (semelhantes às "interfaces" do Java) http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocCategories.html http://developer.apple.com/iphone/library/documentation/cocoa/conceptual/objectivec/Articles/ocProtocols.html#//

apple_ref/doc/uid/TP30001163-CH15-SW1

NSObject 

• Root class 

• Implements many basics 

■ Memory management ■ Introspection ■ Object equality

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 9: OOP ObjC

ObjC: Métodos de Classe e de Instância

• Instâncias respondem a métodos de instância:    - (id)   init;    - (void) setVelMax: (int) vel;        - (int)  velMax;    - (void) travar;    ...

• Classes respondem a métodos de classe:    + (id) alloc;    + (id) Veiculo;    + (Veiculo *) sharedVeiculo;    ...

Page 10: OOP ObjC

ObjC: Mensagens para Objectos• Em ObjC, em vez de se "chamar" métodos de objectos

(como em Java ou C++), enviam-se "mensagens" o Sintaxe:      [receiver message]

         [receiver message:argument]

      [receiver message:arg1 andArg:arg2]    • Exemplos:    

Veiculo *meuVeiculo; //assume this exists...

[meuVeiculo trava];

[meuVeiculo setVelMax:300] //you wish!! ;-)[meuVeiculo vira:90 andPiscaPisca:YES];

int speed = [meuVeiculo velActual];

Page 11: OOP ObjC

ObjC: Mensagens para Objectos

• O "Dot-Syntax"o O ObjC 2.0 introduziu uma outra forma de se aceder a variáveis

membras de um objecto

o O dot-syntax faz uso dos setters e getters!! Não quebra o ENCAPSULAMENTO!!

Veiculo *meuVeiculo; //assume this exists...

int speed1 = [meuVeiculo velActual]; //messageint speed2 = meuVeiculo.velActual; //dot syntax

[meuVeiculo setVelActual: 120]; //messagemeuVeiculo.velActual = 60; //dot syntax

Page 12: OOP ObjC

ObjC: Mensagens para Objectos

• O "Dot-Syntax" - Um problema frequente...o O que é que acontece quando o seguinte código executa?

@implementation Person         - (void)setAge:(int)newAge { //setter            self.age = newAge; //age é uma variável membra        }        @end

o É equivalente a:

        @implementation Person         - (void)setAge:(int)newAge { //setter            [self setAge:newAge]; // Infinite loop!         }        @end

Page 13: OOP ObjC

ObjC: self e super

• self - mensagens para o próprio Objecto

• super - mensagens para o "pai" do Objecto

#import "Veiculo.h"

@implementation Veiculo

-(BOOL) isFamilyVehicle {    return ([self numLugares] >= 4);}

//other method implementations...

-(void) doSomething {    //call superclass implementation first...    [super doSomething];        //now do our own stuff...    int foo = bar;    //... }

Page 14: OOP ObjC

ObjC: tipos dinâmicos e est´ticos

• Objectos com tipos dinâmicoso id anObject; 

apenas id e não id* a não ser que se saiba o que se está a fazer...

tipo genérico: pode ser usado para apontar para qualquer objecto

• Objectos com tipos estáticoso Veiculo *meuVeiculo;

• O ObjC implementa verificação de tipos em compile-time (e não em run-time)

• O ObjC usa sempre "dynamic binding" 

Page 15: OOP ObjC

ObjC: ciclo de vida de objectos

• Criação de Objectoso  Processo de dois passos:

 alocar memória para o objecto: +alloc  inicializar o estado do objecto: -init

Construtor

Veiculo *meuVeiculo = nil;meuVeiculo = [[Veiculo alloc] init];#import "Veiculo.h" 

@implementation Veiculo 

-(id)init {     // allow superclass to initialize its state first     if (self = [super init]) {        velMax = 120;         velActual = 0;        numRodas = 4;        numLugares = 4;     }     return self;} @end

Page 16: OOP ObjC

ObjC: ciclo de vida de objectos

• Criação de Objectos - Métodos init (construtores)o  Uma classe pode definir múltiplos métods init

-(id) init;  -(id) initWithVelMax:(int) vel;  -(id) initWithVelMax:(int) vel velActual:(int) vel; ...

o Métodos menos específicos chamam tipicamente métodos mais específicos usando valores por omissão:

-(id) init {return [self initWithVelMax: 120];}

-(id) initWithVelMax:(int) vel {    return [self initWithVelMax:vel velActual:0];}

Page 17: OOP ObjC

ObjC: ciclo de vida de objectos

• Destruição de Objectos o Depois de criado com com alloc (normalmente seguido de init), e no caso de não mais ser necessário, um objecto deve ser "limpo" da memória!  Para cada alloc deverá haver um dealloc

 caso contrário criam-se "fugas de memória"!! No entanto, dealloc nunca é chamado directamente!

 com uma excepção (ver mais à frente...)  existe um mecanismo para "desalocar" sem chamar dealloc ...  REFERENCE COUNTING

Page 18: OOP ObjC

ObjC: ciclo de vida de objectos• Destruição de Objectos 

o REFERENCE COUNTING Todos os objectos implementam um "retain count"

Herdado de NSObject enquanto o "retain count" > 0, objectivo é mantido em memória e

válido +alloc e -copy criam objectos com "retain count" == 1 -retain incrementa o "retain count" -release decrementa o "retain count" Quando o "retain count" atinge o valor 0 o objecto é destruído!

-dealloc é chamado automaticamente Ponto de não retorno!

Page 19: OOP ObjC

ObjC: ciclo de vida de objectos• Destruição de Objectos - REFERENCE COUNTING

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 20: OOP ObjC

ObjC: ciclo de vida de objectos

• Destruição de Objectos 

Veiculo *meuVeiculo = nil;

meuVeiculo = [[Veiculo alloc] init];

[meuVeiculo setVelMax:120];[meuVeiculo arranca];[meuVeículo setVelActual: 50];//...[meuVeiculo para]; 

//no more need for this object...[meuVeiculo release];

//meuVeiculo will be destroyed in case its retain//count is zero (i.e. no one else is pointing to it)//And in that case, sending messages to it will CRASH![meuVeiculo arranca];//CRASH!!

Page 21: OOP ObjC

ObjC: ciclo de vida de objectos

• Destruição de Objectos 

Veiculo *meuVeiculo = nil;

meuVeiculo = [[Veiculo alloc] init];

[meuVeiculo setVelMax:120];[meuVeiculo arranca];[meuVeículo setVelActual: 50];//...[meuVeiculo para]; 

//no more need for this object...[meuVeiculo release];

meuVeiculo = nil; //good programming practice!

[meuVeiculo arranca];//No longer crashes!:-) No effect...

Page 22: OOP ObjC

ObjC: ciclo de vida de objectos

• Destruição de Objectos - Destrutoro Implementação do método -dealloc 

#import "Veiculo.h"

@implementation Veiculo

-dealloc { //this is an override of NSObject dealloc    //do any cleanup that is necessary...    //...

    //when done, ask super to also clean itself up    [super dealloc]; //only time you call dealloc explicitly!}

//other method implementations...

@end

Page 23: OOP ObjC

ObjC: a classe NSString• Suporte genérico para strings Unicode

o Unicode é um sistema de codificação de caracteres que suporta todas as linguagens do mundo

• Consistentemente usada na API Cocoa e Cocoa Toucho em prejuízo das C-strings (i.e. char *)o sem dúvida uma das classes mais usadas em Cocoa

• Em ObjC, "constant strings" são definidas como:    @“just as simple”

• E "constant strings" são na realidade instâncias de NSString                           NSString *aString = @”Hello World!”;

Page 24: OOP ObjC

ObjC: a classe NSString• Formatação de Strings

o Semelhante ao usado em Java e C++ (e.g. printf) %d - para ints %f  - para floats %c - para chars etc... %@ - para objectos!! --> ObjC

        NSString *aString = @”Johnny”;        NSString *log = [NSString stringWithFormat: @”It’s ‘%@’”, aString];        //log would have been set to: "It’s ‘Johnny’" 

        NSLog(@”I am a %@, I have %d items”, [array className], [array count]);       //Would print: "I am a NSArray, I have 5 items"

Page 25: OOP ObjC

ObjC: apontadores nulos - nil• Apontadores em ObjC podem ser nulos:        int *numberPtr = nil;• Testando um apontador nulo, explicitamente:        if (numberPtr == nil) {return;}

• Testando um apontador nulo, implicitamente:        if (!numberPtr) {return;}• Podem ser usados em atribuições ou argumentos:        numberPtr = nil;        [myCalculator setValue: nil];• Pode-se enviar mensagens para nil (são ignoradas...):        myObject = nil;        [myObject doSomething];

Page 26: OOP ObjC

ObjC: Identidade versus Igualdade entre Objectos

• Identidadeo Teste da igualdade dos respectivos apontadoreso "É o mesmo Objecto?"

    if (object1 == object2) {NSLog(@"Same exact object instance");}

• Igualdadeo Teste da igualdade dos atributos (i.e. variáveis membras de cada objecto)o "Os Objectos têm o mesmo conteudo?" 

    if ([object1 isEqual: object2]) {         NSLog(@"Logically equivalent,                 but may be different object instances");    }

Page 27: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import <Foundation/Foundation.h> 

@interface Veiculo : NSObject { 

    // instance variables     NSString *marca; //Veiculo class “owns” the NSString object 'marca'     int velMax;    //... } 

// method declarations- (void)init; - (NSString *)marca; - (void)setMarca:(NSString *)novaMarca; - (int)velMax;- (void)setVelMax:(int)vel;//... @end

Page 28: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo 

-(id)init {     // allow superclass to initialize its state first     if (self = [super init]) {        marca = @"não definida"; //this is a NSString        velMax = 120;         velActual = 0;        numRodas = 4;        numLugares = 4;     }     return self;}

//other method implementations... @end

Page 29: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo 

- (NSString *)marca { return marca;} 

- (void)setMarca:(NSString *)novaMarca {     marca = novaMarca; //!!! memory leak!!} @end

• Se marca apontasse para uma NSString já existente (e.g. alocada no construtor init da classe Veiculo) essa zona de memória ficaria "em fuga"...

Setter para um objecto criado pelo nosso objecto

Solução 1 (errada)

Page 30: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo 

- (NSString *)marca { return marca;} 

- (void)setMarca:(NSString *)novaMarca {     [marca release]; //what if marca == novaMarca?!?    marca = novaMarca;} @end

• Se por acaso novaMarca apontasse para a mesma NSString que marca aponta (pode acontecer!!), ao fazer release do apontador marca correria-se o risco de o retain counter cair para zero, e a NSString ser destruida!!o perder-se-ia a string que se pretendia usar para passar para o nosso

objecto!!

Setter para um objecto criado pelo nosso objecto

Solução 2 (ainda errada)

Page 31: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo 

- (NSString *)marca { return marca;} 

- (void)setMarca:(NSString *)novaMarca {     if (marca != novaMarca)     {         [marca release];         marca = [novaMarca retain];         // marca’s retain count has been bumped up by 1    }} @end • Antes de tudo verifica-se se por acaso não estamos a receber um

apontador para um objecto NSString para o qual já estamos a apontaro Caso não seja, liberta-se o objecto anterior e aponta-se para o

que é passado como argumento

Setter para um objecto criado pelo nosso objecto

Solução 3a (CORRECTA!)

Page 32: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos#import "Veiculo.h" 

@implementation Veiculo 

- (NSString *)marca { return marca;} 

- (void)setMarca:(NSString *)novaMarca {     if (marca != novaMarca)     {         [marca release];         marca = [novaMarca copy];         // marca’s retain count has been bumped up by 1    }} @end • Neste caso não copiamos apenas o apontador...

o É criada uma cópia do objecto!! Evita que alterações na string por alguém que partilhe

apontadores para a "nossa" NSString marca Na realidade, como o objecto NSString é imutável,

esse problema não se coloca... 

Setter para um objecto criado pelo nosso objecto

Solução 3b (CORRECTA!)

Page 33: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo //...-(void) dealloc {    //do any clean up that is needed...       [marca release];

    //ask super to do its own clean up    [super dealloc]; } @end

• Se alocamos... temos de "desalocar"!!o Caso contrário provocamos uma "fuga de memória" (memory leak)

Oh Yeah! Embrace the power!! ;-)

Page 34: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo //...-(NSString *) descricao { 

    NSString *descricao;

    descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,                com %d lugares...", [self numRodas], [self numLugares]);

    //remember: [NSString alloc] above bumps the retain count (i.e. +1)! 

    return descricao;    } @end

• Retornar um objecto...

• ERRADO! fuga de memória!o [NSString alloc] incrementa o retain count...o Mas em lado algum é feito o correspondente release!

Page 35: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo //...-(NSString *) descricao { 

    NSString *descricao;

    descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,                com %d lugares...", [self numRodas], [self numLugares]);    //remember: [NSString alloc] above bumps the retain count (i.e. +1)!

    [descricao release]; //will this fix the memory leak? Yes... but we return bogus... :-\

    return descricao;    } @end

• Retornar um objecto...

• ERRADO! Retorna um apontador para um objecto inválido!o [NSString alloc] incrementa o retain count...o O release decrementa-o para zero

dealloc é chamado... objecto é destruído Como resolver?!?!

Page 36: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

#import "Veiculo.h" 

@implementation Veiculo //...-(NSString *) descricao { 

    NSString *descricao;

    descricao = [[NSString alloc] initWithFormat:@"Veículo de %d rodas,                com %d lugares...", [self numRodas], [self numLugares]);    //remember: [NSString alloc] above bumps the retain count (i.e. +1)!

    [descricao autorelease]; //nice! ;-)

    return descricao;    } @end

• Retornar um objecto...

• CORRECTO!o É feito o release ao objecto, mas não imediatamente...

Dá-se assim tempo ao código que chamou o método de receber o apontador para um objecto que (ainda é válido!) e de logo a seguir  fazer um retain

o  Quando é então feito o "autorelease"??!

Page 37: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• O autorelease de Objectoso chamando -autorelease "marca" um objecto para ser

enviado um release num momento futuro... o Cumpre-se com o requisito de "emparelhar" cada alloc com

um release Dando algum tempo ao objecto para sobreviver

o Forma conveniente de gerir memória muito útil em métodos que retornam objectos!

Page 38: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• O autorelease e nomes de métodoso Métodos cujos nomes comecem por alloc, copy ou new

 devolvem (i.e. retornam) objectos com retain count == 1 É necessário fazer release quando o objecto não for mais

necessário!! 

o Todos os outros métodos devolvem (i.e. retornam) objectos autoreleased (é apenas uma convenção!!)

NSMutableString *string = [[NSMutableString alloc] init]; // We are responsible for calling -release or -autorelease [string autorelease];

NSMutableString *string = [NSMutableString string]; // The method name doesn’t indicate that we need to release it // So don’t- we’re cool!

Page 39: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?o Objectos são adicionados a um "autorelease pool"o Este "autorelease pool" monitoriza objectos "marcados" para

serem libertados (i.e. released) Quando a própria "autorelease pool" é libertada, todos os objectos

por ela monitorizados são também libertados (i.e. released)o Quando é a "autorelease pool" libertada??

Page 40: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 41: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 42: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 43: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 44: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 45: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 46: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 47: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 48: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 49: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos

• Como funciona o autorelease?

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

Page 50: OOP ObjC

ObjC: reponsabilidade pela vida de Objectos• E não se corre o risco de "a qualquer momento" um objecto

criado com autorelease com ficar inválido e não poder usar um apontador para ele??o Nesse caso, há que fazer retain!

name = [NSMutableString string]; //autoreleased

// We want to name to remain valid! [name retain]; 

// ...

// Eventually, we’ll release it (maybe in our -dealloc?) [name release];

NOTA: autorelease não é Garbage Collection!! 

Page 51: OOP ObjC

Exercício: Classe Calculator e Fraction• Implementar em ObjC uma classe Fraction:

o armazena fracções (i.e. numerador / denominador)o imprime a fracção para a consolao realiza operações (+, -, *, /) entre fracções

#import <Foundation/Foundation.h>#import "Fraction.h"int main (int argc, const char * argv[]) {        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];Fraction *frac1 = [[Fraction alloc] init];        Fraction *frac2 = [[Fraction alloc] init];[frac1 setTo: 1 over: 3];[frac1 print]; //print to console something like "1/3"        [frac2 setTo: 5 over: 4];

        Fraction* result = [frac1 add: frac2]; //adds two fractions        [result print];[frac1 release];        [frac2 release];        [result release][pool drain];return 0;}

Page 52: OOP ObjC

Fim

Cursos de Verão na Católica 2010http://porto.ucp.pt/cvc/

Jorge C. S. Cardoso, Luís Gustavo [email protected], [email protected]

http://slideshare.net/jorgecardoso (tag: cvc2010)

Código fonte: http://db.tt/AOFOfA2