Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在实例化子类时,如何在超类中使用Objective-C工厂方法?_Ios_Objective C_Initialization_Subclass_Factory Pattern - Fatal编程技术网

Ios 在实例化子类时,如何在超类中使用Objective-C工厂方法?

Ios 在实例化子类时,如何在超类中使用Objective-C工厂方法?,ios,objective-c,initialization,subclass,factory-pattern,Ios,Objective C,Initialization,Subclass,Factory Pattern,这个问题是关于子类化一个具有工厂方法的类。我无法使子类正常工作 我有一辆高级轿车。我希望它返回一个Car实例,前提是它能够进行指定距离的旅行,同时考虑到它的燃油消耗量和燃油容量。我为此制作了一个类(工厂)方法 当我从视图控制器调用工厂方法来实例化一辆汽车时,它正是我想要的(代码显示在下面) 现在我还需要卡车,我需要跟踪它们的载货量。我把卡车做成汽车的一个子类 @interface Truck : Car @property (double) cargoCapacityLbs; @end @im

这个问题是关于子类化一个具有工厂方法的类。我无法使子类正常工作

我有一辆高级轿车。我希望它返回一个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**
如果我把车换成卡车也是一样,比如:

Truck *truck1 = [Truck carWith... 20 ...5 ... 60]; //5 gallons enough for 60 miles
B) 在试图进入卡车时发生车祸

cargoCapacityLbs ..unrecognized selector sent to instance <....>**
cargoCapacityLbs..发送到实例的选择器无法识别**
我认为关于子类化,有一些基本的东西我不理解。我曾尝试在卡车初始化方法中直接调用工厂方法,但没有成功

我正在考虑重写Car类,不使用工厂方法,但这似乎很糟糕,因为这样验证就不能在Car类中完成,而必须在view控制器中完成

有什么建议吗?

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);

Instancetype做到了。但我不太高兴有这样的经历

 Car *goodCar = [[self alloc] init];
工厂法

我也看到了这篇博文

所以我换了车:

@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];        
}
}
@接口车
@财产双重烧伤;
@财产双加仑;
@结束
@实施车
-(instancetype)初始化{
返回零;
///避免使用不完整的初始值设定项
}
-(instancetype)initWithBurn:(双)加仑汽油和加仑汽油库存:(双)加仑汽油{
self=[super init];
如果(自我){
_燃烧=每加仑;
_加仑=加仑;
}
回归自我;
}
+(instancetype)createWithFuelConsumption:(双倍)英里每加仑和加仑库存:(双倍)加仑,三英里:(双倍)英里{
如果(MPG*加仑<英里){
返回零;
}否则{
返回[[self alloc]initWithBurn:MPG和gallonsintank:Gallons];
}
}
现在工厂方法中不再引用Car类


(无法将此作为评论发布,太长)

强制转换类型
Truck*t1=(Truck*)[carWith…20…5…60]
@vadian摆脱了编译器警告,但由于无法识别的选择器,应用程序仍然崩溃。实际上它应该是
Truck*t1=(Truck*)[Truck carWith…20…5…60]实例类型完成了它。我对拥有Car*goodCar=[[self alloc]init]不太满意;所以我改变了汽车的执行方式如下:是的,同意;我不太喜欢有车*goodCar=[[self-alloc]init];
@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];        
}
}