Цель C: разница между собой и супер - PullRequest
0 голосов
/ 15 апреля 2011

Я новичок в Objective C. Я пробовал некоторые примеры программ. Я не мог понять, как собственные и супер методы работают в цели C. В программе ниже CashTransaction.m вызывается [super trackSpending: amount] и в CreditCardTransaction.m [self trackSpending: amount] вызван. Я не смог найти разницу между self и 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

Transaction.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

Transaction.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

Ответы [ 3 ]

14 голосов
/ 15 апреля 2011

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 к вашему примеру.

3 голосов
/ 02 августа 2012

self относится к объекту, получающему сообщение при программировании на языке C.

Вызов метода при самостоятельном поиске для реализации метода методом обычным способом, начиная стаблица диспетчеризации класса принимающего объекта.

Пример: [self startThread];self.hostReach = YES;BOOL value = 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

1 голос
/ 15 апреля 2011

Super вызывает перезаписанный метод. Дело в том, что метод в вашем супер пуст.

Если я правильно понимаю вашу идею, то вы хотите создать CashTransactions и CCTransactions и общаться с ними, используя класс Transaction. Таким образом, каждый вызов метода затрат транзакции будет запускать правильный дочерний метод. Это полиморфизм. Вы должны иметь дело только с матерью в классе во время выполнения. Ребенку не нужно супер, если вы не оставите там код, который объединяет всех детей.

...