这个问题是关于对具有工厂方法的类进行子类化。我无法让子类正常工作。
我有班车。我希望它只返回一个Car实例 ,如果能够进行指定距离的旅行,还要考虑它的油耗和燃油容量。我为此制作了一个类(工厂)方法。当我从视图控制器调用工厂方法来实例化汽车时,它完全符合我的要求(代码进一步向下显示)。
@interface Car : NSObject
@end
@implementation Car
- (instancetype) init
{ return [super init]; }
+ (Car *) carWithFuelConsumption:(double)miles_per_gallon
andGallonsInTank:(double)gallons
forTripLength:(double)miles_to_go
{
if (miles_per_gallon * gallons) > miles_to_go) {
Car *goodCar = [[self alloc] init];
return goodCar;
} else {
return nil;
}
现在我还需要卡车,我需要跟踪他们的货物容量。我把卡车变成了Car的子类。
@interface Truck : Car
@property (double) cargoCapacityLbs;
@end
@implementation Truck
- (instancetype) init {
self = [super init];
if (self) {
self.cargoCapacity= 2000.0;
}
return self;
}
在我的视图控制器中,我可以很好地实例化汽车:
Car *car1 = [Car carWith... 20 ...5 ... 60]; //5 gallons enough for 60 miles
Car *car2 = [Car carWith... 20 ...5 ... 90];
/// car2 is nil, 5 gallons NOT enough for 60 miles at 20 miles per gallon.
但是一辆卡车让我
A)编译器警告
Truck *t1 = [Car carWith... 20 ...5 ... 60]; //5 gallons enough for 60 miles
**incompatible pointer types assigning to Truck from Car**
如果我将Car改为Truck,就像这样:
Truck *truck1 = [Truck carWith... 20 ...5 ... 60]; //5 gallons enough for 60 miles
B)尝试访问truck1.cargoCapacityLbs
时发生崩溃cargoCapacityLbs ..unrecognized selector sent to instance <....>**
我认为有一些基本的东西,我不了解子类化。我试过直接在卡车初始化方法中调用工厂方法,没有运气。
我正在考虑重写Car类,不使用工厂方法,但这似乎很糟糕,因为验证不能在Car类中完成,而且必须在视图控制器中完成。
有什么建议吗?
答案 0 :(得分:2)
A)您使用工厂方法的方法是合法的,应该正常工作。
要删除编译器警告,请在工厂方法声明中使用instancetype
作为结果类型:
+ (instancetype) carWithFuelConsumption:(double)miles_per_gallon
andGallonsInTank:(double)gallons
forTripLength:(double)miles_to_go;
B)从上面的代码中,您应该能够访问cargoCapacityLbs
而不会崩溃(也许您刚刚拼错了名字?)。这是我使用的代码,它运行正常:
@interface Car : NSObject
+ (instancetype) carWithFuelConsumption:(double)miles_per_gallon
andGallonsInTank:(double)gallons
forTripLength:(double)miles_to_go;
@end
@implementation Car
+ (instancetype) carWithFuelConsumption:(double)miles_per_gallon
andGallonsInTank:(double)gallons
forTripLength:(double)miles_to_go
{
if(miles_per_gallon * gallons > miles_to_go) {
Car *goodCar = [[self alloc] init];
return goodCar;
} else {
return nil;
}
}
@end
@interface Truck : Car
@property double cargoCapacityLbs;
@end
@implementation Truck
- (instancetype) init {
self = [super init];
if (self) {
self.cargoCapacityLbs = 2000.0;
}
return self;
}
@end
Truck* t1 = [Truck carWithFuelConsumption:5 andGallonsInTank:44 forTripLength:3];
NSLog(@"%f", t1.cargoCapacityLbs);
答案 1 :(得分:0)
Instancetype做到了。但我对
感到不满意 Car *goodCar = [[self alloc] init];
在工厂方法中。
我也发现了这篇博文 http://ernstsson.net/post/80915338055/objective-c-class-factory-methods
所以我改变了汽车:
@interface Car
@property double burn;
@property double gallons;
@end
@implementation Car
- (instancetype) init {
return nil;
///preclude use of an incomplete initializer
}
- (instancetype) initWithBurn:(double)MPG andGallonsInTank:(double) gallons {
self = [super init];
if (self) {
_burn = MPG;
_gallons = gallons;
}
return self;
}
+ (instancetype) createWithFuelConsumption:(double)MPG andGallonsInTank:(double)Gallons forTripLength:(double) miles {
if (MPG * Gallons < miles) {
return nil;
} else {
return [[self alloc] initWithBurn:MPG andGallonsInTank:Gallons];
}
}
现在工厂方法中没有更多对Car类的引用。
(无法发布此评论,这太长了)