Đa kế thừa Objective-C


88

Tôi có 2 lớp một bao gồm methodA và một bao gồm methodB. Vì vậy, trong một lớp mới, tôi cần ghi đè các phương thức methodA và methodB. Vậy làm cách nào để đạt được đa kế thừa trong mục tiêu C? Tôi hơi nhầm lẫn với cú pháp.

Câu trả lời:


136

Objective-C không hỗ trợ đa kế thừa và bạn không cần nó. Sử dụng thành phần:

@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

Bây giờ bạn chỉ cần gọi phương thức trên ivar có liên quan. Nó nhiều mã hơn, nhưng không có đa kế thừa như một tính năng ngôn ngữ trong mục tiêu-C.


8
Thành phần thường là một cách tiếp cận tốt hơn so với kế thừa, đặc biệt nếu bạn thực hiện nhiều thử nghiệm đơn vị trên mã. Nó linh hoạt hơn nhiều ở chỗ bạn có thể dễ dàng hoán đổi các triển khai mà không cần xác định lại chính lớp đó. Đặc biệt tiện dụng khi bạn muốn hoán đổi ClassA và ClassB cho các đối tượng giả. Ngay cả trong thời gian chạy, việc hoán đổi các triển khai (ví dụ FTPFileStore vs LocalFileStore) trở nên sạch sẽ hơn với thành phần. Điều đó không có nghĩa là thừa kế không có nó diễn ra mặc dù, nhưng nhu cầu cho đa kế thừa sẽ đề nghị mà tôi lại nghĩ rằng thiết kế của tôi;)
d11wtq

1
Tôi không hiểu điều này. Bạn không cần phải khởi tạo ClassAClassB? Liệu gọi methodA:vào MyClassbằng cách nào đó tự động gọi methodA:về ClassA?
zakdances

1
Không, nhưng bạn vẫn có thể chia sẻ hành vi thông qua truyền tin nhắn, cách OOP ban đầu được cho là hoạt động. Nếu bạn không ngay lập tức nghĩ rằng bạn cần kế thừa và thay vào đó xem xét một giải pháp sử dụng thành phần, bạn sẽ thấy mình bắt đầu cấu trúc các chương trình của mình theo cách dễ bảo trì hơn. Tất nhiên ObjC có tính kế thừa cơ bản cho những trường hợp sử dụng nó là đúng.
d11wtq 10/09/13


1
d11wtq, câu trả lời tuyệt vời! Ngoài ra, chuyển tiếp tin nhắn cho phép bạn bỏ qua bước thực hiện lại methodA và methodB. Tin nhắn có thể được chuyển tiếp tự động đến các đối tượng thích hợp chỉ với một chút thao tác. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
arsenius

3

Đây là cách tôi viết mã singletonPattern với tư cách là "cha mẹ" Về cơ bản, tôi đã sử dụng kết hợp giao thức và danh mục.

Điều duy nhất tôi không thể thêm là một "ivar" mới, tuy nhiên, tôi có thể đẩy nó với đối tượng liên quan.

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

}

Bất cứ khi nào tôi muốn một lớp "kế thừa" BGSuperSingleton này, tôi chỉ cần làm:

#import "NSObject+singleton.h"

và thêm @interface MyNewClass () <BGSuperSingleton>


2
Danh mục không phải là đa kế thừa. Chúng là một cách bổ sung các phương thức / hàm vào một lớp đã tồn tại. Đa kế thừa cho phép lớp thứ ba là sự kết hợp của một HOẶC NHIỀU lớp (bao gồm cả các biến). Tôi thích thể loại. Danh mục rất hữu ích. Nhưng chúng KHÔNG phải là đa kế thừa.
Lloyd Sargent,

Nhưng một lớp con của UIViewController cũng có thể "hỗ trợ", trong trường hợp này, tôi muốn mẫu singleton.
Septiadi Agus

Về mặt kỹ thuật, tất cả NSManagedObject "hiện có thể gọi" [obj singleton]. Tôi đặt những thứ tôi muốn với sự hỗ trợ của giao thức. Dù sao cũng tốt như đa kế thừa. Điều này chỉ xảy ra nếu tôi muốn lớp con hỗ trợ cả giao diện và việc triển khai của cha mẹ. Nếu chỉ thực hiện thì rõ ràng bố cục là con đường để đi.
Septiadi Agus

Chỉ cần thêm giao thức như <BGSuperSingleton> không làm cho các lớp có thể gọi phương thức "singleton". Bạn vẫn phải triển khai nó ...
CommaToast

-4

Bạn có biết về Giao thức không, giao thức là cách để thực hiện đa kế thừa


12
+1 "Để nắm bắt điểm tương đồng giữa các lớp không liên quan theo thứ bậc." developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
pokstad

7
Trong trường hợp này, khi cả hai phương thức sẽ bị ghi đè, các giao thức sẽ thực hiện thủ thuật. Trong các trường hợp khác khi bạn muốn sử dụng kế thừa để sử dụng lại mã, các giao thức sẽ không hữu ích. Tuy nhiên, điều này thường có thể được giải quyết bằng cách để các lớp cha kế thừa lẫn nhau hoặc bằng cách kết hợp chúng, thường có một cách để giải quyết nó đúng nếu một lớp con thực sự chia sẻ mã với 2 lớp.
jake_hetfield

bạn có thể kết hợp giao thức với một danh mục hoặc thành phần.
Septiadi Agus

-1 vì Giao thức không có ở đó cho đa kế thừa. Tương tự JAVA, Interfaceskhông cung cấp hoặc bắt chước đa kế thừa.
thesummersign

1
@FreeAsInBeer Từ tài liệu riêng của Apple Một giao thức tuyên bố một giao diện lập trình mà bất kỳ lớp nào cũng có thể chọn để triển khai. Các giao thức giúp cho hai lớp có quan hệ xa nhau do kế thừa có thể giao tiếp với nhau để hoàn thành một mục tiêu nhất định. Do đó, họ cung cấp một giải pháp thay thế cho phân lớp con . Như bạn có thể thấy Apple rõ ràng đang sử dụng phân lớp tức là kế thừa. Có lẽ Nikesh bao gồm điều này trong câu trả lời của riêng mình sẽ hữu ích để làm sáng tỏ lập luận của mình
Honey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.