self
и super
работают совершенно по-разному: self
означает вызывающий объект в время выполнения , а super
означает суперкласс класса, в котором находится определение метода.В обоих случаях они указывают, где должен начинаться поиск метода, в случае self
начальная точка определяется динамически, в случае super
она известна во время компиляции.
ЗдесьПридуманный пример:
@interface Grandparent : NSObject
- (void) One;
@end
@implementation Grandparent
- (void) One { NSLog(@"Grandparent One\n"); }
@end
@interface Parent : Grandparent
- (void) One;
- (void) Two;
@end
@implementation Parent
- (void) One { NSLog(@"Parent One\n"); }
- (void) Two
{
[self One]; // will call One based on the calling object
[super One]; // will call One based on the defining object - Parent in this case so will Grandparent's One
}
@end
@interface Child : Parent
- (void) One;
@end
@implementation Child
- (void) One { NSLog(@"Child One\n"); }
@end
@implementation FamilyAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
Child *c = [Child new];
[c Two]; // will call the Two inherited from Parent
Parent *p = [Parent new];
[p Two]; // will call Parent's Two
}
@end
Итак, у нас есть три класса;Grandparent
, Parent
и Child
;каждый с методом One
.Класс Parent has a method
Два which calls
Один on
Сам and
Супер`.Выполнение этого приводит к:
2011-04-15 22:49:05.006 Family[1993:a0f] Child One
2011-04-15 22:49:05.009 Family[1993:a0f] Grandparent One
2011-04-15 22:49:05.009 Family[1993:a0f] Parent One
2011-04-15 22:49:05.010 Family[1993:a0f] Grandparent One
Для случая Child
вызов [c Two]
вызывает метод Two
, который Child
наследует от его Parent
- поэтому у нас есть наследование.
Теперь, когда Two
выполняет, он сначала вызывает [self One]
, а self
является экземпляром Child
, который имеет One
, поэтому Child
One
выполняется - это основано на наследованииполиморфизм;во время определения Parent
Two
будущее существование Child
неизвестно, но во время выполнения вызов [self One]
может вызвать метод Child
.
СледующийЗвоните Two
[super One]
.Теперь известно, что это относится к Grandparent
One
во время определения.
В общем super
не относится к методу в суперклассе (как в этом примере), но к методу вызовет объект, тип которого является суперклассом, например, он может принадлежать, скажем, Greatgrandparent
.Однако любой вызываемый метод может быть определен во время компиляции, поскольку известна родословная любого класса.
Вызовы [self *method*]
и [super *method*]
могут даже вызывать один и тот же метод, найденный динамически в первом случае,и известен статически в последнем.
Надеюсь, теперь вы можете применить наследование, self
и super
к вашему примеру.