title: What's the best way to cast a custom Class in PHP
body: <p>I know off the bat some of you will assume Interface or Abstract, but that only handles SOME of the situations.  Here's an example where they break.</p>
  
  <p>Assume we have classes that implement the same interface and extend the same base</p>
  
  <pre><code>  class car extends fourwheeler implements ipaygas{       
  
      protected $tank1;
  
      //interface
      public function payGas($amount){}
  
    }
  
    class sportscar extends fourwheeler implements ipaygas{
  
      protected $tank1;
      protected $tank2;
  
      //interface
      public function payGas($amount){}
  
    }
  
    interface ipaygas{
  
      function payGas($amount);
    }
  </code></pre>
  
  <p>In some situations an interface is all you need as you may only want to execute 'payGas()'.  But what do you do when you have conditions to be met.</p>
  
  <p>Example, what if - before paying gas you need to (1) check the car type, (2) use premium gas for the sports car, and (3) fill the second tank of the sports car.</p>
  
  <p>THIS IS WHAT I WANT TO DO BUT CANNOT</p>
  
  <pre><code>   function pumpAndPay(iPayGas $car){
       if(gettype($car) == "car"){
         fillTank($car,(car) $car-&gt;tank1);
       }else{
         fillTank($car,(sportscar) $car-&gt;tank1);
         fillTank($car,(sportscar) $car-&gt;tank2);
       }
     }
  </code></pre>
  
  <p>How can I do this with real type casting?  Is it possible in PHP?</p>
  
  <p>Update (Based on responses):
  In my 'real' case... imagine I have to check various Vehicle types, each with different paint, body, interior, gas_type, cleaner_type, color, etc... </p>
  
  <pre><code>   abstract class AVechicle{}
     abstract class ACar extends AVechicle{}
     abstract class ATruckOrSUV extends AVechicle{}
     abstract class ABike extends AVechicle{}
  
     class Car extends ACar{}
     class SportsCar extends ACar{}
     class SUV extends ATruckOrSUV{}
     class Truck extends ATruckOrSUV{}
     class Bike extends ABike{}
     class Scooter extends ABike{}
  
     class GasStation{
  
       public function cleanVehicle(AVehicle $car){
         //assume we need to check the car type to know
         //what type of cleaner to use and how to clean the car
         //if the car has leather or bucket seats
  
         //imagine we have to add an extra $2/h for sports cars
  
         //imagine a truck needs special treatment tires
         //or needs inspection
       }
  
       public function pumpAndPay(AVehicle $car){
         //need to know vehicle type to get gas type
  
         //maybe we have a special for scooters only, Green Air campaign etc.
       }
  
       public function fullService(AVehicle $car){
         //need to know if its a truck to do inspection FIRST
  
         $this-&gt;cleanVehicle($car);
         $this-&gt;pumpAndPay($car);
  
         //bikes get 10% off
         //cars get free carwash
       }
  
     }
  </code></pre>
  
  <p>Interfaces and abstracts alone will only go so far... </p>