0

Objective CI は初めてで、いくつかのサンプル プログラムを試しています。self メソッドと super メソッドが Objective C でどのように機能するか理解できませんでした。 trackSpending:amount] が呼び出されます。self と super.super の違いが見つかりませんでした。super は、基本クラスのオーバーライドされたメソッドを呼び出すためのものです。self は、子クラスのオーバーライドされたメソッドを呼び出すためのものです。これが私の理解です。私は間違っています。よろしくお願いします。

main.m

#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;
}

BudgetObject.h

#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

BudgetObject.m

#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

トランザクション.h

#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

トランザクション.m

#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

CashTransaction.h

#import <Cocoa/Cocoa.h>
#import "Transaction.h"
@interface CashTransaction : Transaction {

}
@end

CashTransaction.m

#import "CashTransaction.h"
#import "BudgetObject.h"
@implementation CashTransaction
- (void) spend{
        [super trackSpending:amount];
        [budget spendDollars:amount];
}
@end

CreditCardTransaction.h

#import <Cocoa/Cocoa.h>
#import "Transaction.h"
@interface CreditCardTransaction : Transaction {

}
@end

CreditCardTransaction.m

#import "CreditCardTransaction.h"
#import "BudgetObject.h"
@implementation CreditCardTransaction
- (void) spend {
        [self trackSpending:amount];
        [budget changeForeignCurrency:amount];
}
@end

出力:

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
4

3 に答える 3

15

self実行時の呼び出しオブジェクトを意味し、メソッド定義があるクラスのスーパークラスを意味しsuperます。どちらの場合も、メソッドの検索を開始する場所を指定しています。開始点が動的に決定される場合、コンパイル時に既知の場合です。selfsuperselfsuper

以下は構成例です。

@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

したがって、3 つのクラスがあります。GrandparentParentおよびChild; それぞれにメソッドがありOneます。クラスParent has a methodツーワンwhich callsセルフonand`。これを実行すると、次が生成されます。

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]はそのメソッドTwoChild継承するメソッドを呼び出すParentので、継承があります。

Two実行されると、最初に呼び出さ[self One]れ、 を持つのselfインスタンスであるため、が実行されます。これは、継承ベースのポリモーフィズムです。の定義時点ではの将来の存在は不明ですが、実行時には呼び出しでのメソッドを呼び出すことができます。ChildOneChildOneParentTwoChild[self One]Child

次の着信はTwoです[super One]。現在、これは定義時にを参照することGrandparentが知られています。One

一般superに、 はスーパークラスのメソッドを参照しませんが (この例のように)、スーパークラスが呼び出すオブジェクトのメソッドを参照します。たとえば、 に属することができGreatgrandparentます。ただし、任意のクラスの祖先がわかっているため、呼び出されるメソッドはコンパイル時に決定できます。

前者の場合は動的に検出され、後者の場合は静的に認識される同じメソッドを呼び出すことができ[self *method*]ます。[super *method*]

うまくいけば、継承を適用​​して、例に適用できselfますsuper

于 2011-04-15T11:18:26.740 に答える
3

selfは、Objective-Cプログラミングでメッセージを受信するオブジェクトを指します。

自己でメソッドを呼び出すと、受信オブジェクトのクラスのディスパッチテーブルから開始して、通常の方法でメソッドのメソッド実装が検索されます。

例:[self startThread]; self.hostReach = YES; BOOL値=self.hostReach;

1.selfは、新しい値を割り当てても、さまざまな方法で使用できる変数名でもあります。2.インスタンスメソッド内では、selfはインスタンスを参照します。ただし、クラスメソッド内では、selfはクラスオブジェクトを参照します。

superは、非常に異なる場所でメソッド実装を検索するようにコンパイラーに指示するフラグです。これは、superが出現するメソッドを定義するクラスのスーパークラスで始まります。

superがメッセージを受信するたびに、コンパイラはobjc_msgSend関数の代わりに別のメッセージングルーチンを使用します。置換ルーチンは、メッセージを受信するオブジェクトのクラスではなく、定義クラスのスーパークラス、つまり、メッセージをスーパーに送信するクラスのスーパークラスを直接参照します。スーパーへのメッセージにより、メソッドの実装を分散できます。複数のクラス。 

一部のタスクでは、継承階層の各クラスは、ジョブの一部を実行し、残りのメッセージをsuperに渡すメソッドを実装できます。新しく割り当てられたインスタンスを初期化するinitメソッドは、このように機能するように設計されています。各initメソッドは、そのクラスで定義されたインスタンス変数を初期化する責任があります。ただし、そうする前に、初期化メッセージをsuperに送信して、継承元のクラスにインスタンス変数を初期化させます。initの各バージョンはこの手順に従うため、クラスは継承の順序でインスタンス変数を初期化します。

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocDefiningClasses.html

于 2012-08-02T15:23:51.633 に答える
1

Super は、上書きされたメソッドを呼び起こします。つまり、スーパーのメソッドは空です。

あなたの考えが正しければ、CashTransactions と CCTransactions を作成し、Transaction クラスを使用してそれらと対話する必要があります。そうすれば、トランザクションの支出メソッドを呼び出すたびに、正しい子メソッドがトリガーされます。それがポリモーフィズムです。実行時にマザー クラスを処理するだけで済みます。すべての子に共通するコードをそこに残さない限り、子はスーパーを必要としません。

于 2011-04-15T09:13:01.857 に答える