Если существует жесткая граница между типами автомобилей и типами топлива, то FillTank()
не имеет права находиться в базовом классе Car
, поскольку знание того, что у вас есть автомобиль, не говорит вам, какое топливо , Таким образом, для обеспечения правильности во время компиляции , FillTank()
должно быть определено в подклассах и должно принимать только подкласс Fuel
, который работает.
Но что, если у вас есть общий код, который вы не хотите повторять между подклассами? Затем вы пишете защищенный FillingTank()
метод для базового класса, который вызывает функция подкласса. То же самое относится и к Fuel
.
Но что, если у вас есть какая-нибудь волшебная машина, работающая на нескольких видах топлива, скажем, дизельное или газовое? Затем этот автомобиль становится подклассом DieselCar
и GasCar
, и вам необходимо убедиться, что Car
объявлен как виртуальный суперкласс, чтобы у вас не было двух экземпляров Car
в объекте DualFuelCar
. Заполнение резервуара должно просто работать с небольшими изменениями или без изменений: по умолчанию вы получите DualFuelCar.FillTank(GasFuel)
и DualFuelCar.FillTank(DieselFuel)
, что дает вам перегруженную по типу функцию.
Но что, если вы не хотите, чтобы у подкласса была функция FillTank()
? Затем вам нужно переключиться на проверку во время выполнения и выполнить то, что, как вы думали, нужно: сделать проверку подкласса Fuel.type
и либо сгенерировать исключение, либо вернуть код ошибки (предпочтительнее последнего), если есть несоответствие. В C ++ RTTI и dynamic_cast<>
- это то, что я бы порекомендовал. В Python isinstance()
.