Warisan ganda Objective-C


88

Saya memiliki 2 kelas satu termasuk methodA dan yang lainnya termasuk methodB. Jadi di kelas baru saya perlu mengganti metode methodA dan methodB. Jadi bagaimana cara mencapai multiple inheritance dalam tujuan C? Saya agak bingung dengan sintaksnya.

Jawaban:


136

Objective-C tidak mendukung multiple inheritance, dan Anda tidak membutuhkannya. Gunakan komposisi:

@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

Sekarang Anda hanya perlu menjalankan metode pada ivar yang relevan. Ini lebih banyak kode, tetapi tidak ada banyak warisan sebagai fitur bahasa di objektif-C.


8
Komposisi sering kali merupakan pendekatan yang lebih baik untuk diambil daripada warisan, terutama jika Anda melakukan banyak pengujian unit pada kode. Ini memberikan lebih banyak fleksibilitas karena Anda dapat dengan mudah menukar implementasi tanpa mendefinisikan ulang kelas itu sendiri. Sangat berguna ketika Anda ingin, katakanlah, menukar ClassA dan ClassB untuk objek tiruan. Bahkan saat runtime menukar implementasi (misalnya FTPFileStore vs LocalFileStore) menjadi lebih bersih dengan komposisi. Itu tidak berarti warisan tidak memiliki tempatnya, tetapi kebutuhan akan banyak warisan akan menyarankan agar saya memikirkan kembali desain saya;)
d11wtq

1
Saya tidak mengerti ini. Apakah Anda tidak perlu memberi contoh ClassAdan ClassB? Apakah menyerukan methodA:pada MyClassentah bagaimana panggilan secara otomatis methodA:pada ClassA?
zakdances

1
Tidak, tetapi Anda masih dapat berbagi perilaku melalui penyampaian pesan, cara kerja OOP yang semula seharusnya. Jika Anda tidak langsung berpikir bahwa Anda memerlukan warisan dan malah mempertimbangkan solusi menggunakan komposisi, Anda akan menemukan Anda mulai menyusun program dengan cara yang lebih mudah dipelihara. Tentu saja ObjC memiliki warisan dasar untuk kasus-kasus yang benar untuk menggunakannya.
d11wtq


1
d11wtq, jawaban bagus! Sebagai tambahan, penerusan pesan memungkinkan Anda melewati langkah penerapan ulang methodA dan methodB. Pesan dapat secara otomatis diteruskan ke objek yang sesuai hanya dengan sedikit kerja. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
arsenius

3

Ini adalah bagaimana saya mengkodekan singletonPattern sebagai "orang tua" Pada dasarnya saya menggunakan kombinasi protokol dan kategori.

Satu-satunya hal yang tidak dapat saya tambahkan adalah "ivar" baru. Namun, saya dapat mendorongnya dengan objek terkait.

#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
{

}

Setiap kali saya ingin kelas untuk "mewarisi" BGSuperSingleton ini, saya hanya melakukan:

#import "NSObject+singleton.h"

dan tambahkan @interface MyNewClass () <BGSuperSingleton>


2
Kategori bukanlah warisan ganda. Mereka adalah cara untuk menerapkan metode / fungsi ke kelas yang sudah ada. Warisan berganda memungkinkan kelas ketiga menjadi kombinasi dari satu ATAU LEBIH kelas (termasuk variabel). Saya suka kategori. Kategori sangat berguna. Tetapi mereka BUKAN warisan ganda.
Lloyd Sargent

Tetapi subclass dari UIViewController juga dapat "mendukung", dalam hal ini, pola tunggal yang saya inginkan.
Septiadi Agus

Secara teknis semua NSManagedObject "sekarang dapat memanggil" [obj singleton]. Saya mengatur yang saya inginkan dengan dukungan protokol. Sebagus beberapa warisan. Ini hanya jika saya ingin kelas anak untuk mendukung antarmuka dan implementasi induk. Jika hanya implementasinya maka jelas komposisi adalah jalan yang harus ditempuh.
Septiadi Agus

Hanya menambahkan protokol seperti <BGSuperSingleton> tidak membuat kelas kemudian dapat memanggil metode "tunggal". Anda masih harus menerapkannya ...
CommaToast

-4

Apakah Anda tahu tentang Protokol, protokol adalah cara untuk mengimplementasikan multiple inheritance


12
+1 "Untuk menangkap kesamaan di antara kelas-kelas yang tidak terkait secara hierarki." developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
pokstad

7
Dalam kasus ini, di mana kedua metode akan diganti, protokol akan melakukan triknya. Dalam kasus lain ketika Anda ingin menggunakan warisan untuk menggunakan kembali kode, protokol tidak akan membantu. Namun hal ini biasanya dapat diselesaikan dengan membiarkan kelas superkelas mewarisi satu sama lain, atau dengan menggabungkannya, biasanya ada cara untuk memperbaikinya jika subkelas benar-benar berbagi kode dengan 2 kelas.
jake_hetfield

Anda dapat menggabungkan protokol dengan kategori atau komposisi.
Septiadi Agus

-1 karena Protokol tidak ada untuk multiple inheritance sama sekali. Demikian pula JAVA, Interfacestidak untuk memberikan atau meniru beberapa warisan.
tanda tangan musim panas

1
@FreeAsInBeer Dari dokumentasi Apple sendiri Sebuah protokol menyatakan antarmuka programatik yang dapat dipilih oleh kelas mana pun untuk diterapkan. Protokol memungkinkan dua kelas yang terkait jauh oleh warisan untuk berkomunikasi satu sama lain untuk mencapai tujuan tertentu. Dengan demikian, mereka menawarkan alternatif untuk subclass . Seperti yang Anda lihat, Apple secara eksplisit menggunakan subclassing yaitu mewarisi. Mungkin Nikesh memasukkan ini dalam jawabannya sendiri akan membantu untuk mengklarifikasi argumennya
Madu
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.