我對Objective C很陌生。
假設有 3 個類:Chef、Food、Dishs
正如您所料:A Chef cook Food -> Dish。
- (Dishe *)cook:(Food *)food;
現在我想添加 ChefFish、Fish 和 FishDish 類。
如您所料:當廚師烹制魚時,我們將有 FishDish
我自然會去:
- (FishDishe *)fishTraitment:(Fish *)fish {
return [FishDishe alloc];
}
- (Dishe *)cook:(Food *)food {
if ([food isKindOfClass:[Fish class]]) {
return [self fishTraitement:food];
} else {
return [Dishe alloc];
}
}
然后我收到了這個警告:
Incompatible pointer types sending 'Food *' to parameter of type 'Fish *'
當然,代碼本身可以按預期編譯和運行。
警告不是真正的問題,因為我們可以通過強制轉換來避免它,或者只是在 cook 方法中移動 fishTraitment 塊。
但是四處搜索,我發現一些話題說使用 isKindOfClass 不是“干凈的”。
這將違反多型性和面向物件的原則。
我的問題在這里:
這里的最佳做法是什么?
Note that i could have elsewhere, an array of Chef that with generic Chef and ChefFish.
I would expect:
Chef cook fish -> Dishe
ChefFish cook fish -> FishDishe
Have also though about overloading, looks like we can't have method with same name & same number of parameters (event with different type & name), which is possible in Swift :(
uj5u.com熱心網友回復:
Objective-C 中沒有 C 中已知的多載。
盡量避免宣告具有未使用引數的方法。如果你這樣做,你只會讓你的堆疊浪費比需要更多的記憶體。
所有的 Objective-C 物件通常都在某個時候從 NSObject 繼承。所以它們都默認繼承了一些方法。例如:alloc, init, new(立即呼叫 alloc init), dealloc.
@interface Cook : NSObject
-(instancetype)init; //default anyway..
@end
@interface Fish : NSObject
-(instancetype)initWithCook:(Cook*)cook; //not default
// so Fish has also one 'init' method even if not declared explicit.
@end
@interface Dish : NSObject
-(instancetype)initWithCook:(Cook*)cook;
-(instancetype)initWithCook:(Cook*)cook AndFish:(Fish*)fish;
@end
@interface SmellyFish : Fish
-(void)washSmellyDish:(Dish*)dish;
@end
您可以查看 NSObject 的宣告并遍歷默認方法,因此任何NS Object 也繼承。
上面的例子:Cook、Dish 和 Fish 繼承自 NSObject,所以你可以詢問[object isKindOfClass:[NSObject class]]哪個有點多余,因為幾乎任何 objc-object 在某些時候都繼承自 NSObject。但是 SmellyFish 繼承自 Fish here,因此您可以詢問isKindOfClass Fish、SmellyFish 還是 NSObject,它應該回答是。
如果您需要確保某些 obj 屬于某些特定類,請改為使用
[obj isMemberOfClass:[Fish class]]
所以也許你會做類似的事情..
-(FishDish *)fishDish {
return [FishDish new];
}
-(Dish *)cook:(id)food {
if ([food isKindOfClass:[Fish class]]) {
return [self fishDish];
} else {
return [[Dish alloc] init];
}
}
看到了(id)food嗎?id是一種特定于 Objective-C 的資料型別,表示 some (any kind of) 的 C 指標NSObject。你也可以寫出id<SuperFood> food你期望一些遵循某些特定協議的指標作為物件參考。類似于(SuperFood*)food, whereSuperFood*將宣告它必須是指向一個SuperFood物件的指標。
maybe also a good practise is avoiding casting before asking for compliance to specific data types, because it is possible to make a method call to isKindOfClass worthless by just casting.
You want to check, so avoid casting.
Because if you cast to much and actually don't know the data type given in reference you are better off by just using id or NSObject*. This practice also keeps you from importing more code just to declare some specific datatype when you don't even use its methods in that part of implementation file.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/451118.html
標籤:objective-c oop
上一篇:DataGrid不過濾?
