C:self 和super的区别

Objective C: Difference between self and super

我刚接触到目标C。我正在尝试一些示例程序。我无法理解目标C中的self和super方法是如何工作的。在cashtransaction下面的pgm中,调用m[超级跟踪支出:金额],在creditcardttransaction中调用m[自我跟踪支出:金额],我找不到self和super之间的区别。super用于调用基类overriden method.and self是为了调用子类overrided method。这是我的理解。如果我错了,请纠正我。谢谢在advace中。

主m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#import <Foundation/Foundation.h>
#import"BudgetObject.h"
#import"Transaction.h"
#import"CashTransaction.h"
#import"CreditCardTransaction.h"

int main (int argc, const char * argv[]) {

        //!---Creating An Object And Allocating It With Values---
        Budget* budget = [Budget new];
        [budget createBudget:1000.00 withExchangeRate:1.2500];

        //!---Declaring And Adding Elements To An Array---
        NSMutableArray* transactions = [[NSMutableArray alloc] initWithCapacity:10];
        Transaction* aTransaction;
        aTransaction = [Transaction new];
        [transactions addObject:aTransaction];

        //!---Calculating The No Of Elements In An Array---
        int k;
        k=[transactions count];
        NSLog(@"The count value is:%d",k);

        //!---Selecting According To The Type Of Transaction---
    for(Transaction *iTransaction in transactions){
         switch ([aTransaction returnType]) {
                case cash:
                        [budget spendDollars:[iTransaction returnAmount]];
                        break;
                case credit:
                        [budget changeForeignCurrency:[iTransaction returnAmount]];
                        break;
                default:
                        break;
         }
        }

        Budget* europeBudget = [Budget new];
        [europeBudget createBudget:1000.00 withExchangeRate:1.2500];

        Budget* englandBudget = [Budget new];
        [englandBudget createBudget:2000.00 withExchangeRate:1.5000];

        NSMutableArray* transactions = [[NSMutableArray alloc] initWithCapacity:10];
        Transaction* aTransaction;
        for(int n=1;n<2;n++){
                aTransaction = [CashTransaction new];
                [aTransaction createTransaction:n*100 forBudget:europeBudget];
                [transactions addObject:aTransaction];

                aTransaction = [CashTransaction new];
                [aTransaction createTransaction:n*100 forBudget:englandBudget];
                [transactions addObject:aTransaction];  
        }
        int n=1;
        while (n<4) {
                aTransaction = [CreditCardTransaction new];
                [aTransaction createTransaction:n*100 forBudget:europeBudget];
                [transactions addObject:aTransaction];

                aTransaction = [CreditCardTransaction new];
                [aTransaction createTransaction:n*100 forBudget:englandBudget];
                [transactions addObject:aTransaction];

                n++;    
        }
        for(Transaction* aTransaction in transactions){
                [aTransaction spend];
        }
return 0;
}

预算对象

1
2
3
4
5
6
7
8
9
10
#import <Cocoa/Cocoa.h>
@interface Budget : NSObject {
        float exchangeRate;
        double budget;
        double exchangeTransaction;
}
- (void) createBudget: (double) aBudget withExchangeRate: (float) anExchangeRate;
- (void) spendDollars: (double) dollars;
- (void) changeForeignCurrency: (double) foreignCurrency;
@end

预算对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import"BudgetObject.h"
@implementation Budget
- (void) createBudget: (double) aBudget withExchangeRate: (float) anExchangeRate;
{
        budget = aBudget;
        exchangeRate = anExchangeRate;
}
- (void) spendDollars: (double) dollars
{
        budget = budget - dollars;
        NSLog(@"Converting %0.2f into U.S Foreign Currency leaves $%0.2f",dollars,budget);
}
- (void) changeForeignCurrency: (double) foreignCurrency
{
        exchangeTransaction = foreignCurrency * exchangeRate;
        budget = budget - exchangeTransaction;
        NSLog(@"Charging %0.2f in Foreign Currency leaves $%0.2f",foreignCurrency,budget);
}
@end

事务处理

1
2
3
4
5
6
7
8
9
10
11
#import <Cocoa/Cocoa.h>
#import"BudgetObject.h"
@class Budget;
@interface Transaction : NSObject {
        Budget* budget;
        double amount;  
}
- (void) createTransaction: (double) theAmount forBudget: (Budget*) aBudget;
- (void) trackSpending: (double) theAmount;
- (void) spend;
@end

事务处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import"Transaction.h"
#import"BudgetObject.h"
@implementation Transaction
- (void) createTransaction: (double) theAmount forBudget: (Budget*) anBudget {
        budget = anBudget;
        amount = theAmount;
}
- (void) spend {

}
-(void) trackSpending: (double) theAmount {
        NSLog(@"You are about to spend another %0.2f",theAmount);
}
@end

现金交易.h

1
2
3
4
5
6
#import <Cocoa/Cocoa.h>
#import"Transaction.h"
@interface CashTransaction : Transaction {

}
@end

现金交易.m

1
2
3
4
5
6
7
8
#import"CashTransaction.h"
#import"BudgetObject.h"
@implementation CashTransaction
- (void) spend{
        [super trackSpending:amount];
        [budget spendDollars:amount];
}
@end

信用卡交易.h

1
2
3
4
5
6
#import <Cocoa/Cocoa.h>
#import"Transaction.h"
@interface CreditCardTransaction : Transaction {

}
@end

信用卡交易.m

1
2
3
4
5
6
7
8
#import"CreditCardTransaction.h"
#import"BudgetObject.h"
@implementation CreditCardTransaction
- (void) spend {
        [self trackSpending:amount];
        [budget changeForeignCurrency:amount];
}
@end

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2011-04-15 11:24:46.112 Bud Obj1[1041:a0f] You are about to spend another 100.00
2011-04-15 11:24:46.114 Bud Obj1[1041:a0f] Converting 100.00 into U.S Foreign Currency leaves $900.00
2011-04-15 11:24:46.115 Bud Obj1[1041:a0f] You are about to spend another 100.00
2011-04-15 11:24:46.115 Bud Obj1[1041:a0f] Converting 100.00 into U.S Foreign Currency leaves $1900.00
2011-04-15 11:24:46.116 Bud Obj1[1041:a0f] You are about to spend another 100.00
2011-04-15 11:24:46.119 Bud Obj1[1041:a0f] Charging 100.00 in Foreign Currency leaves $775.00
2011-04-15 11:24:46.120 Bud Obj1[1041:a0f] You are about to spend another 100.00
2011-04-15 11:24:46.120 Bud Obj1[1041:a0f] Charging 100.00 in Foreign Currency leaves $1750.00
2011-04-15 11:24:46.121 Bud Obj1[1041:a0f] You are about to spend another 200.00
2011-04-15 11:24:46.121 Bud Obj1[1041:a0f] Charging 200.00 in Foreign Currency leaves $525.00
2011-04-15 11:24:46.122 Bud Obj1[1041:a0f] You are about to spend another 200.00
2011-04-15 11:24:46.122 Bud Obj1[1041:a0f] Charging 200.00 in Foreign Currency leaves $1450.00
2011-04-15 11:24:46.123 Bud Obj1[1041:a0f] You are about to spend another 300.00
2011-04-15 11:24:46.123 Bud Obj1[1041:a0f] Charging 300.00 in Foreign Currency leaves $150.00
2011-04-15 11:24:46.124 Bud Obj1[1041:a0f] You are about to spend another 300.00
2011-04-15 11:24:46.125 Bud Obj1[1041:a0f] Charging 300.00 in Foreign Currency leaves $1000.00

selfsuper的工作方式截然不同:self表示运行时的调用对象,super表示方法定义所在的类的超类。在这两种情况下,它们都指定了方法的搜索应该从哪里开始,在self的情况下,起始点是动态确定的,在super的情况下,在编译时就知道了。

下面是一个组合示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@interface Grandparent : NSObject

- (void) One;

@end

@implementation Grandparent

- (void) One { NSLog(@"Grandparent One
"
); }

@end

@interface Parent : Grandparent

- (void) One;
- (void) Two;

@end

@implementation Parent

- (void) One { NSLog(@"Parent One
"
); }

- (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
"
); }

@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

所以我们有三个类:GrandparentParentChild;每个类都有一个方法One。类Parent has a methodtwowhich callsoneonselfeandsuper `。运行此程序会产生:

1
2
3
4
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情况,调用调用Child从其Parent继承的方法Two,因此我们有继承权。

现在,当Two执行时,它首先调用[self One]selfChild的一个实例,它有一个One,所以ChildOne被执行-这是基于继承的多态性;在定义ParentTwo时,Child的未来存在是未知的,但在执行时我调用[self One]可以调用Child的方法。

Two中的下一个调用是[super One]。现在我们知道,在定义时,这是指GrandparentOne

一般来说,super并不引用超类中的方法(在本例中是这样),但对于方法,类型为超类的对象将调用,例如,它可以属于Greatgrandparent。然而,无论调用什么方法,都可以在编译时确定,因为任何类的祖先都是已知的。

调用[self *method*][super *method*]甚至可以调用相同的方法,在前一种情况下动态找到,在后一种情况下静态知道。

希望您现在可以将继承,selfsuper应用到您的示例中。


self refers to the object receiving a message in objective-C programming.

在自调用方法时,以通常的方式搜索方法的方法实现,从接收对象类的调度表开始。

示例:【self-startthread】;self.hostreach=yes;bool值=self.hostreach;

1.self也是一个变量名,可以以任何方式使用,甚至可以分配一个新值。2.在实例方法中,self指的是实例;而在类方法中,self指的是类对象。

super is a flag that tells the compiler to search for the method implementation in a very different place. It begins in the superclass of the class that defines the method where super appears.

只要super接收到消息,编译器就会为objc msgsend函数替换另一个消息传递例程。替换例程直接查找定义类的超类,即发送消息给super的类的超类,而不是接收消息的对象的类。发送给super的消息允许方法实现分布在多个类上。

对于某些任务,继承层次结构中的每个类都可以实现一个方法,该方法执行部分任务,并将消息传递给其余的super。初始化新分配的实例的init方法设计为这样工作。每个init方法都有责任初始化其类中定义的实例变量。但在执行此操作之前,它会向super发送一条init消息,让它继承的类初始化其实例变量。每个版本的init都遵循此过程,因此类按照继承顺序初始化其实例变量。

http://developer.apple.com/library/ios/documentation/cocoa/conceptive/obiodic/chapters/ocdefiningclasses.html


super调用覆盖方法。问题是,你的超能力中的方法是空的。

如果我理解您的想法是正确的,那么您需要创建cashtransactions和cctransactions,并使用transaction类与它们进行交谈。这样,每次调用Transaction Spend方法都会触发正确的子方法。这就是多态性。您只需要在运行时处理母亲类。孩子不需要超人,除非你给他们留下一些共同的代码。