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. Это больше кода, но в Objective-C просто нет множественного наследования как языковой особенности.


8
Композиция очень часто является лучшим подходом, чем наследование, особенно если вы проводите много модульного тестирования кода. Он обеспечивает гораздо большую гибкость, поскольку вы можете легко менять реализации, не переопределяя сам класс. Это особенно удобно, если вы хотите, например, поменять местами ClassA и ClassB на фиктивные объекты. Даже при замене реализаций во время выполнения (например, FTPFileStore и LocalFileStore) композиция становится чище. Это не значит, что наследованию нет места, но необходимость множественного наследования
заставляет

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

1
Нет, но вы все равно можете поделиться поведением с помощью передачи сообщений, как изначально предполагалось работать с ООП. Если вы сразу же не подумаете, что вам нужно наследование, а вместо этого рассмотрите решение с использованием композиции, вы обнаружите, что начинаете структурировать свои программы более удобным для сопровождения способом. Конечно, ObjC имеет базовое наследование для тех случаев, когда его правильно использовать.
d11wtq


1
d11wtq, отличный ответ! Кроме того, пересылка сообщений позволяет пропустить этап повторной реализации methodA и methodB. Сообщения могут быть автоматически переадресованы соответствующим объектам с небольшим трудом. 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 также может «поддерживать», в данном случае, шаблон singleton, если я хочу.
Septiadi Agus

Технически все NSManagedObject «теперь могут вызывать» [obj singleton]. Я устанавливаю те, которые хочу, с поддержкой протокола. В любом случае, все равно, что множественное наследование. Это только в том случае, если я хочу, чтобы дочерний класс поддерживал как интерфейс, так и реализацию родительского. Если только реализация, то очевидно, что композиция - это путь.
Septiadi Agus

Простое добавление протокола, такого как <BGSuperSingleton>, не позволяет классам затем вызывать метод «singleton». Вам все еще нужно его реализовать ...
CommaToast

-4

Знаете ли вы о протоколах, протоколы - это способ реализации множественного наследования


12
+1 «Чтобы зафиксировать сходство между классами, которые не связаны иерархически». developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
pokstad

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

вы можете комбинировать протокол с категорией или составом.
Septiadi Agus

-1 потому что протоколы вообще не предназначены для множественного наследования. Аналогичным образом, в JAVA, Interfacesне предоставлять или имитируют множественное наследование.
лето 01

1
@FreeAsInBeer Из собственной документации Apple Протокол объявляет программный интерфейс, который может реализовать любой класс. Протоколы позволяют двум классам, отдаленно связанным наследованием, общаться друг с другом для достижения определенной цели. Таким образом, они предлагают альтернативу подклассу . Как видите, Apple явно использует подклассы, то есть наследование. Возможно, Никеш, включив это в свой ответ, поможет прояснить его аргумент
Дорогая,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.