2011-12-15 49 views
5

Tôi có kinh nghiệm với lập trình hướng đối tượng tuy nhiên tình huống này không quen thuộc với một số lý do. Hãy xem xét mã Mục tiêu-c 2.0 sau đây:Phương thức gọi trên lớp con từ phương thức lớp cha (Mục tiêu-c 2.0)

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

Đây có phải là cách đúng để gọi phương thức trên lớp con từ phương thức trong lớp cha mẹ không? Điều gì sẽ xảy ra nếu một lớp con khác không thực hiện phương thức g? Có lẽ có một cách tốt hơn để giải quyết điều này giống như một phương thức trừu tượng trong lớp cha A?

+1

thể trùng lặp của [Gửi thông điệp tới trẻ em từ cha mẹ] (http://stackoverflow.com/questions/3351937/sending-message-to -con-từ-cha mẹ) –

+1

Cũng thấy: [Gọi lớp con của phương thức từ siêu lớp của nó] (http://stackoverflow.com/questions/7515582/call-subclasss-method-from-its-superclass) –

Trả lời

11

Điều quan trọng là phải có phương thức trong lớp cha có thể bị ghi đè trong lớp con.

@interface Dog : NSObject 
- (void) bark; 
@end 

@implementation Dog 
- (void) bark { 
    NSLog(@"Ruff!"); 
} 
@end 

@interface Chihuahua : Dog 
@end 

@implementation Chihuahua 
- (void) bark { 
    NSLog(@"Yipe! Yipe! Yipe!"); 
} 
@end 

Bạn thấy đấy, lớp con của bạn sẽ ghi đè phương thức gốc bằng cách triển khai riêng. Bạn có thể thấy nó được sử dụng như thế này:

Dog *someDog = [Chihuahua alloc] init] autorelease]; 
[someDog bark]; 

Output: Yipe! Yipe! Yipe!

+0

Làm cho tinh thần. Có 'bark' cần phải được khai báo trong giao diện lớp cha? – SundayMonday

+1

'bark' phải được khai báo trong giao diện của bạn. Vâng. – Jeremy

+1

Có thể có một tình huống khác mà bạn thực sự muốn gọi một phương pháp khác như phương pháp bạn đã mô tả. Ví dụ: bạn có thể muốn sử dụng mẫu mẫu: [mẫu phương thức mẫu] (http://en.wikipedia.org/wiki/Template_method_pattern), như thể bạn muốn gọi 'bark' như trong ví dụ của tôi, tuy nhiên, bark sau đó sẽ gọi một số phương thức nội bộ mà sau đó sẽ bị ghi đè bởi lớp con, sorta giống như ví dụ của Squeegy. – Jeremy

3

Bạn nên triển khai g trong lớp cha, nhưng không làm gì cả. Bằng cách này, nó có thể được gọi mà không có lỗi, nhưng vẫn có thể bị ghi đè.

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
- (void) g {} // Does nothing in baseclass 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

Hoặc bạn kiểm tra phương pháp trên đối tượng trước khi thực hiện.

if ([self respondsToSelector:@selector(g)]) { 
    [self performSelector:@selector(g) withObject:nil]; 
} 

Nhưng điều đó có thể trở nên khá xấu.

+0

Trình biên dịch kích hoạt cảnh báo mặc dù, phải không? Vì biên dịch nghĩ rằng nó biết rằng lớp 'self' không thực hiện phương thức đó? –

Các vấn đề liên quan