2012-06-12 2 views
0

У меня есть базовый класс, который имеет методы класса, определенные для возврата различных частей информации, которые я использую для создания URL-адреса службы. Базовый класс также имеет метод экземпляра, определенный для создания этого URL-адреса. Я хотел бы, чтобы базовый класс имел реализацию этого метода по умолчанию, поэтому мне нужно только переопределить его в моих подклассах, когда мне нужно, чтобы URL-адрес был другим. Как этот базовый метод вызывает переопределенные методы класса для создания URL-адреса с использованием методов класса из подкласса? Ниже приведен код, который я теперь не работает:Вызов методов, переопределенных в подклассе из суперкласса

Метод базового класса:

- (NSString *)buildRequestUrlString{ 
    return [Utils serviceEndpointForOperationId:[[self class]operationId] version:[[self class] operationVersion] andRequestMethod:[[self class] methodType]; 
} 

OperationID, operationVersion и methodType являются методы класса, которые реализуются в подклассе, но когда подкласс делает следующий вызов:

[super buildRequestUrlString]; 

Он использует методы класса из базового класса, чтобы построить свою конечную точку, а не методы класса в моем подклассе. Как я могу сделать это не так? Возможно ли это?

Спасибо заранее,

Ник

ответ

0

Я бы использовал шаблон шаблона для этого. В основном создайте 3 метода экземпляра в своем базовом классе, чтобы получить вашу операциюId и т. Д. В базовом классе они просто возвращают нуль. Затем в ваших подклассах переопределите эти 3 метода, чтобы вернуть правильные значения.

Ваш метод buildRequestUrlString использует [сам OperationID] и т.д.

+0

Это именно то, что я сделал, за исключением того, что они не являются методами экземпляра, они являются методами класса. Это будет работать, если они являются методами экземпляра, но я не мог использовать методы экземпляра, потому что я использую эти методы для других вещей в других местах, и методы экземпляра не будут работать в этих случаях. –

+0

Вернувшись и посмотрев на это, я понял, что забыл переопределить три метода класса. Именно поэтому он не выполнял базовую реализацию этих трех методов класса. Спасибо за всю твою помощь. –

1

Использование self вместо super.

[self buildRequestUrlString]; 

(Или объясните, почему это не работает в вашем случае).

В ответ на комментарий, это звучит как ваша Декомпозиция класса неверно (или вы запутались). В частности, это, вероятно, почему вы получили три ответа, которые все «использовали self»; мы не понимаем, где проблема.

Если вашему базовому классу необходимо вызвать метод экземпляра из подкласса, ему нужна ссылка на экземпляр подкласса. То есть говорят, что у вас есть:

@interface Concrete:Base 

Затем база может реализовать метод класса, как:

+ baseWithConcreteQuantity:(int)aQuant 
{ 
    return [[self alloc] initWithConcreteQuantity:aQuant]; 
} 

И это будет использоваться как:

[Concrete baseWithConcreteQuantity:10]; 

То есть методы класса в объективно- C - в отличие от статических методов на других языках - наследуются так же, как и методы экземпляра.

Теперь, что касается метода экземпляра, вы всегда вызываете реализацию super определенного метода из этого метода. Использование super для звонка Разное метод базового класса в значительной степени никогда сделано и является верным признаком того, что что-то еще не так.

Аналогичным образом базовый класс никогда не должен пытаться специально назначать функциональные возможности в подклассе, который не существует в базе.

I.e.

// in base 
... 
[self doSomething]; 
... 

- (void)doSomething { ; } 

// where a subclass might 
- (void)doSomething { ... ; [super doSomething]; } 
+0

Это не будет работать, потому что это будет затем рекурсивный вызов. Я хочу, чтобы определить поведение по умолчанию этого метода в суперклассе. Когда метод фактически вызывается в подклассе, поскольку подкласс не имеет определения для buildRequestUrlString, он будет использовать реализацию класса по умолчанию для этого класса. Но в реализации суперклассов по умолчанию я хочу, чтобы он использовал переопределенные версии подкласс классов методов operationId, opeartionVersion и methodType. –

0

В вашем «buildRequestUrlString» -метод ваше [само класс], очевидно, типа «базовый класс».

Руководство по наследованию объектов настоятельно не согласуется с попыткой получить доступ к свойствам подклассов вашего отцовского класса, поскольку у класса отца есть (и должно быть) отсутствие знаний о существовании подклассов.

Guess, я не типа достаточно быстро, чтобы решить эту проблему делать то, что bbum сказал;)

EDIT: This'd быть хак, и против того, что я только что сказал, но вы можете сдать класс -name в качестве аргумента:

- (NSString *)buildRequestUrlString:(Class)theClass{ 
    if (!theClass) theClass = [self class]; 
    return [Utils serviceEndpointForOperationId:[theClass operationId] version:[theClass operationVersion] andRequestMethod:[theClass methodType]]; 
} 

[super buildRequestUrlString:[self class]]; 
+0

Ответ bbum не был тем, что я искал, поэтому не чувствую себя плохо :) Методы, которые я хочу вызвать в подклассе, определены в суперклассе. Я просто хочу, чтобы суперкласс использовал переопределенную версию этих методов. Вся идея того, что я пытаюсь выполнить, - не дублировать один и тот же код снова и снова для каждого из моих подклассов, которые должны использовать стандартную реализацию этого метода. Это очень легко сделать на C# и просто работает из коробки. –

+0

Я думал об этом как о решении, но я согласен, что это будет взлом. Есть ли способ определить тип класса, который фактически выполняет метод внутри этого метода? Если бы я мог это сделать, я мог бы, вероятно, сделать эту работу. –

+0

ну, если вы запустите [self Class] в любом методе, который вы получите в текущем классе, этот метод будет запущен ... Я мог бы неправильно понять вас, если это извините за очевидный ответ ... – Bersaelor