Этот вопрос касается подклассификации класса с заводским методом. Я не могу заставить подкласс работать правильно.Как я могу использовать метод Objective-C в суперклассе при создании экземпляра подкласса?
У меня есть класс автомобиля. Я хочу, чтобы он возвращал экземпляр автомобиля только, если он способен совершить поездку на указанное расстояние, учитывая также расход топлива и топливную мощность. Для этого я сделал классный (заводский) метод.
Выполняет именно то, что я хочу, когда я вызываю фабричный метод с моего контроллера представления, чтобы создать экземпляр автомобиля (код показан ниже).
@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;
}
Теперь мне также нужны грузовики, для которых мне необходимо отслеживать их грузоподъемность. Я сделал Truck подклассом 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) и сбой при попытке получить доступ к truck1.cargoCapacityLbs
cargoCapacityLbs ..unrecognized selector sent to instance <....>**
Я думаю, что есть что-то фундаментальное, я не понимая о подклассов. Я попытался вызвать фабричный метод непосредственно в методе инициализации грузовика, не повезло.
Я думаю о переписывании класса Car, чтобы не использовать заводской метод, но это кажется плохим, потому что тогда проверка не может быть выполнена в классе Car и должна выполняться в контроллере представления.
Любые предложения?
Cast тип 'Грузовик * t1 = (Truck *) [Автомобиль carWith ... 20 ... 5 ... 60]; ' – vadian
@vadian, который избавляется от предупреждения компилятора, но приложение все еще выходит из строя из-за нераспознанного селектора. –
На самом деле это должно быть «Грузовик» t1 = (Грузовик *) [Грузовой автомобиль с ... 20 ... 5 ... 60]; ' – Leonardo