2015-12-02 62 views
0

我有ClassAClassB,我想從ClassA繼承ClassB來簡化我的代碼。的問題是,幾乎所有的不同之處在於共享用於ClassA我有一個通用的陣列,像這樣:Objective-C的泛型 - 有沒有辦法使類的泛型匹配(在繼承的情況下)

@property NSMutableArray<ClassADataType*> objectsArray; 

而對於ClassB我有一個通用的陣列:

@property NSMutableArray<ClassBDataType*> 

類似地,對於ClassA我有一個屬性一個類實例,像這樣:

@property ClassADataType* object 

ClassB我有一個PROPERT Ÿ像這樣

@property ClassBDataType* object 

ClassBDataTypeClassADataType繼承,同樣我想提出ClassB繼承ClassA。有沒有辦法做到這一點,基本上覆蓋類繼承類的類屬性?

回答

3

不,這將違反Liskov Substitution,特別是因爲它們是可寫的可變屬性。例如:

ClassA *a = [ClassB new]; // Legal and proper because B is an A. 
a.object = [ClassADataType new]; // "Legal," but completely broken. 

(如果他們是不可改變的性質,原則上這種功能可能存在不會產生這些問題,但ObjC不提供該功能,即使在有限的情況下,這是很難證明財產是總是只讀在ObjC。)

在大多數情況下,正確的答案是不使用繼承。通常最好通過組合(幫助對象)而不是類層次來處理共享代碼。這是尤其如此,因爲你說這是「簡化我的代碼」。除非你可以說「以各種方式,B是更具體的A」,否則你不應該創建繼承。說「他們有很多共同的代碼」是不夠好的。

如果您確實需要使用繼承,常用技巧是向B下推另一個屬性。

@property (readonly) ClassBDataType* classBObject; 

- (ClassBDataType *) classBObject { 
    return (ClassBDataType *)self.classAObject; 
} 

據這些屬性是隻讀到外面的世界,否則你可以得到上面提到的不一致性在這種情況下非常重要。

0

除了Rob的回答。我有類似的情況,我認爲可能有繼承的情況,但是如果B不是AI的直接後代,那麼最好的模式是A和B都繼承的抽象類baseAB,並且它擁有所有的共享代碼。

對於類型化的數組屬性,那麼每個子類都可以擁有它自己的,但這可能不是那麼好,因爲很多代碼不能移動到基類。取決於這個陣列對班級的中心位置。

然後,該選項可以將基本類中的通用數組屬性與ClassADataTypeClassBDataType的共享祖先一起使用,但這可能會打破輸入數組的想法。

或者您可以跳過數組的泛型,使其成爲基類的iVar,並在子類中提供自定義類型方法來設置和獲取值並進行類型檢查。