Я относительно новичок в Objective-C, и я думал о том, что все методы, по сути, являются виртуальными.Я создал эту небольшую консольную программу:
#import <Foundation/Foundation.h>
@interface BaseClass : NSObject
{
}
- (void) virtualMethod: (NSInteger) integer;
@end
@interface DerivedClass : BaseClass
{
}
- (void) virtualMethod: (NSString *) string;
@end
@implementation BaseClass
- (void) virtualMethod: (NSInteger) integer
{
NSLog(@"%ld", integer);
}
@end
@implementation DerivedClass
- (void) virtualMethod: (NSString *)string
{
NSLog(@"%@", string); // Program received signal: "EXC_BAD_ACCESS". -- as expected
}
@end
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *arr = [NSArray arrayWithObjects: [BaseClass new], [DerivedClass new], nil];
for (int i = 0; i < arr.count; i++)
{
BaseClass *b = (BaseClass *)[arr objectAtIndex: i];
[b virtualMethod: i];
}
NSLog(@"\n\nTapos na!\n\n");
[pool drain];
return 0;
}
Как и ожидалось, я получил EXC_BAD_ACCESS
в производном virtualMethod:
, поскольку, в конце концов, он не принимает целое число, он принимает NSString *
в качестве параметра.Виртуальный механизм основан на селекторах и, похоже, не учитывает подписи.
Мой вопрос: есть ли в языке что-то, что могло бы предотвратить такое переопределение с другой сигнатурой?Какой-то способ сказать компилятору, что virtualMethod:
всегда должен иметь одну и ту же сигнатуру, или заставить компилятор выдавать какую-то подсказку, предупреждение или ошибку, если сигнатура не совпадает?
Я знаю, что это хорошопрограммист всегда указывает имена типов, которые должен иметь метод, но это соглашение, а не правило языка.Я спрашиваю о функции компилятора, чтобы предотвратить возникновение проблемы.