Vamos considerar a seguinte classe:
@interface Veiculo : NSObject {
NSString *modelo;
float potencia;
}
-(void) apresentacao;
-(id) init: (NSString *) _modelo: (float) _potencia;
-(NSString *) getModelo;
-(float) getPotencia;
-(void) setModelo: (NSString *) _modelo;
-(void) setPotencia: (float) _potencia;
@end
@implementation Veiculo
-(void) apresentacao {
NSLog(@"O %@ é do modelo %@, potência %.1f.", [self class], modelo, potencia);
}
-(id) init: (NSString *) _modelo: (float) _potencia {
modelo = _modelo;
potencia = _potencia;
}
-(NSString *) getModelo {
return modelo;
}
-(float) getPotencia {
return potencia;
}
-(void) setModelo: (NSString *) _modelo {
modelo = _modelo;
}
-(void) setPotencia: (float) _potencia {
potencia = _potencia;
}
@end
Para fazer uma herança, basta substituir o NSObject pela classe desejada. Caso tenha sobreposição de construtor ou outro método, use o super
. Veja um exemplo:
@interface Carro : Veiculo
-(id) init: (NSString *) _modelo: (float) _potencia;
@end
@implementation Carro
-(id) init: (NSString *) _modelo: (float) _potencia {
[super init: _modelo: _potencia];
}
@end
Instanciação da classe:
Veiculo *fusca = [[Carro alloc] init: @"Fusca": 1.6];
[fusca apresentacao];
A mesma classe Veiculo pode gerar outras classes, como por exemplo Moto e Onibus.
PS: O Objective-C não suporta herança múltipla.
Podemos simular classes e métodos abstratos, assim:
@interface Energia : NSObject
-(void) ligar;
-(void) desligar;
@end
@implementation Energia
-(void) ligar {
[NSException raise: @"Implemente o método \"ligar\"" format: @""];
}
-(void) desligar {
[NSException raise: @"Implemente o método \"desligar\"" format: @""];
}
@end
E as classes herdeiras:
@interface Lampada : Energia
// Métodos sobrepostos
-(void) ligar;
-(void) desligar;
@end
@implementation Lampada
-(void) ligar {
NSLog(@"A Lâmpada está acesa!");
}
-(void) desligar {
NSLog(@"A Lâmpada apagou!");
}
@end
A outra classe:
@interface Televisao : Energia
// Métodos sobrepostos:
-(void) ligar;
-(void) desligar;
@end
@implementation Televisao
-(void) ligar {
NSLog(@"A TV está ligada!");
}
-(void) desligar {
NSLog(@"A TV desligou!");
}
@end
A instanciação:
Energia *lamp = [[Lampada alloc] init];
[lamp ligar];
[lamp desligar];
Energia *tv = [[Televisao alloc] init];
[tv ligar];
[tv desligar];
PS: Qualquer método pode ser sobreposto, caso chame ele na classe filha, use o método [super nomeDoMetodo]
para isso. As classes com métodos abstratos e interfaces não podem ser instanciadas. E Objective-C não suporta sobrecarga de métodos.
Vamos supor essa classe:
@interface Pilha : NSObject {
NSString *marca;
int carga;
}
-(id) init: (NSString *) _marca;
-(void) apresentacao;
-(NSString *) getMarca;
-(int) getCarga;
-(void) setMarca: (NSString *) _marca;
-(void) setCarga: (int) _carga;
@end
@implementation Pilha
-(id) init: (NSString *) _marca {
marca = _marca;
carga = 100;
}
-(void) apresentacao {
NSLog(@"A marca da pilha é %@.", marca);
NSLog(@"A carga da pilha é %d%%.", carga);
}
-(NSString *) getMarca {
return marca;
}
-(int) getCarga {
return carga;
}
-(void) setMarca: (NSString *) _marca {
marca = _marca;
}
-(void) setCarga: (int) _carga {
carga = _carga;
}
@end
Nós podemos fazer relacionamentos entre clases diferentes, veja por exemplo a classe abaixo, que tem um atributo do "tipo" da classe acima:
@interface Aparelho : NSObject {
Pilha *pl;
}
-(id) init: (Pilha *) _pl;
-(void) ligado;
-(Pilha *) getPl;
-(void) setPl: (Pilha *) _pl;
@end
@implementation Aparelho
-(id) init: (Pilha *) _pl {
pl = _pl;
}
-(void) ligado {
if([pl getCarga] > 0) { // Getter do objeto Pilha
NSLog(@"O aparelho está ligado e a carga da pilha é de %d%%!", [pl getCarga]);
}
else {
NSLog(@"A pilha do aparelho está sem carga!");
}
}
-(Pilha *) getPl {
return pl;
}
-(void) setPl: (Pilha *) _pl {
pl = _pl;
}
@end
Aí podemos chamar os objetos assim:
Pilha *ray = [[Pilha alloc] init: @"Rayovac"];
[ray apresentacao];
Aparelho *controle = [[Aparelho alloc] init: ray];
[controle ligado];
NSLog(@"A carga da pilha é de %d%%!", [[controle getPl] getCarga]);