Objective-C множинне успадкування


88

У мене є 2 класи, один включає методA, а інший - методB. Тож у новому класі мені потрібно замінити методи methodA та methodB. Отже, як мені досягти множинного успадкування за ціллю C? Я трохи плутаюсь із синтаксисом.

Відповіді:


136

Objective-C не підтримує множинне успадкування, і вам це не потрібно. Склад використання:

@interface ClassA : NSObject {
}

-(void)methodA;

@end

@interface ClassB : NSObject {
}

-(void)methodB;

@end

@interface MyClass : NSObject {
  ClassA *a;
  ClassB *b;
}

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;

-(void)methodA;
-(void)methodB;

@end

Тепер вам просто потрібно викликати метод у відповідному ivar. Це більше код, але просто не існує багаторазового успадкування як мовної функції у object-C.


8
Композиція дуже часто є кращим підходом, ніж успадкування, особливо якщо ви проводите багато модульних тестів на коді. Це надає набагато більшу гнучкість у тому, що ви можете легко поміняти місцями реалізації без перевизначення самого класу. Особливо зручно, коли ви хочете, скажімо, поміняти місцями ClassA та ClassB на макетні об’єкти. Навіть під час виконання обмінних реалізацій (наприклад, FTPFileStore проти LocalFileStore) стає чистішим за складом. Це не означає, що спадкування не має свого місця, однак потреба у багаторазовому успадкуванні означатиме, що я переосмислю свій дизайн;)
d11wtq

1
Я цього не розумію. Вам не потрібно створювати екземпляри ClassAта ClassB? Робить виклик methodA:на MyClassяк - то автоматично дзвонити methodA:на ClassA?
zakdances

1
Ні, але ви все одно можете поділитися поведінкою шляхом передачі повідомлень, як OOP спочатку мав працювати. Якщо ви не відразу перейдете до думки, що вам потрібне успадкування, а замість цього розглянете рішення із використанням композиції, ви почнете структурувати свої програми більш ремонтопридатним способом. Звичайно, ObjC має базове успадкування для випадків, коли правильно використовувати його.
d11wtq


1
d11wtq, чудова відповідь! Крім того, переадресація повідомлень дозволяє пропустити крок повторної реалізації методуA та методуB. Повідомлення можна автоматично пересилати до відповідних об’єктів, лише трохи попрацювавши. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
arsenius 02

3

Ось як я кодую singletonPattern як "батьківський" В основному я використовував комбінацію протоколу та категорії.

Єдине, що я не можу додати, це новий "ivar", однак, я можу підштовхнути його до пов'язаного об'єкта.

#import <Foundation/Foundation.h>
@protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
@end

@interface NSObject (singleton) <BGSuperSingleton>

@end

static NSMutableDictionary * allTheSingletons;

+(instancetype)singleton
{
    return [self singleton1];
}
+(id) singleton1
{
    NSString* className = NSStringFromClass([self class]);

    if (!allTheSingletons)
    {
        allTheSingletons = NSMutableDictionary.dictionary;
    }

    id result = allTheSingletons[className];

    //PO(result);
    if (result==nil)
    {
        result = [[[self class] alloc]init];
        allTheSingletons[className]=result;
        [result additionalInitialization];
    }
    return result;
}

-(void) additionalInitialization
{

}

Щоразу, коли я хочу, щоб клас "успадкував" цей BGSuperSingleton, я просто роблю:

#import "NSObject+singleton.h"

і додати @interface MyNewClass () <BGSuperSingleton>


2
Категорії не є множинним успадкуванням. Вони є способом спрямування методів / функцій на вже існуючий клас. Множинне успадкування дозволяє третьому класу бути комбінацією одного АБО БОЛЬШЕ класів (включаючи змінні). Мені подобаються категорії. Категорії дуже корисні. Але вони НЕ є багаторазовим успадкуванням.
Ллойд Сарджент

Але підклас UIViewController також може "підтримувати", в цьому випадку, я хочу побачити односторонній шаблон.
Септіаді Агус,

Технічно всі NSManagedObject "тепер можуть викликати" [obj singleton]. Я встановлюю бажаних за допомогою протоколу. Так чи інакше, як багаторазове успадкування. Це лише в тому випадку, якщо я хочу, щоб дочірній клас підтримував як інтерфейс, так і реалізацію батьківського. Якщо лише реалізація, то очевидно склад - це шлях.
Септіаді Агус,

Просто додавання протоколу типу <BGSuperSingleton> не робить класи тоді викликами методу "singleton". Вам все одно доведеться це реалізувати ...
CommaToast

-4

Чи знаєте ви про протоколи, протоколи - це спосіб реалізації множинного успадкування


12
+1 "Для виявлення подібності між класами, які не пов’язані з ієрархією." developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
pokstad

7
У цьому випадку, коли обидва методи будуть замінені, протоколи зроблять свою справу. В інших випадках, коли ви хочете використовувати спадщину для повторного використання коду, протоколи не допоможуть. Однак це зазвичай можна вирішити, дозволивши класам суперкласи успадковувати один одного, або комбінуючи їх, як правило, є спосіб це виправити, якщо підклас насправді ділиться кодом з 2 класами.
jake_hetfield

Ви можете поєднувати протокол або з категорією, або з композицією.
Септіаді Агус

-1, оскільки протоколів взагалі немає для багаторазового успадкування. Подібним чином у JAVA, Interfacesне повинні надавати чи імітувати багаторазове успадкування.
літній підпис

1
@FreeAsInBeer З власної документації Apple Протокол оголошує програмний інтерфейс, який будь-який клас може вибрати для реалізації. Протоколи дозволяють спілкуванню між собою двох класів, віддалено пов’язаних між собою за спадщиною, для досягнення певної мети. Таким чином, вони пропонують альтернативу підкласуванню . Як бачите, Apple явно використовує підкласи, тобто успадкування. Можливо, Нікеш, включивши це у власну відповідь, було б корисним для роз'яснення свого аргументу
Мед,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.