TL;DR: you can do
class LoopClass(){
    ...
    Car car = new Car();
    Bicycle bicycle = new Bicycle();
    LoopClass(){
        ArrayList<TickInterface> rides = new ArrayList<TickInterface>();
        rides.add(car);
        rides.add(bicycle);
    }
    void thisLoopsEveryFrame(){
        for(TickInterface ride : rides){
            ride.tick();
        }
    }
    void refuelCar(){
        car.refuel(); // possible now car has compile-time type of Car
    }
}
Explanation:
You're confusing "compile-time type" and "runtime type": the statement
I want to call tick() on both different objects with same interface
  but this causes me not being able to call refuelCar() from Car object.
is not true.
The methods that an object actually has, i.e. the members of the object, are determined by the actual type of the object in memory at runtime (the "runtime type"). This in turn is determined by the constructor that was used to create the object.
So when you write
TickInterface car = new Car();
then when this code is executed at runtime, it creates an object in memory (on the heap) of type Car. You can think of this object as having both a tick() method and a refuel() method.
On the other hand, the methods the compiler will allow you to call are determined by the compile-time type: that is, the type of the reference variable used to refer to an object.
By writing
TickInterface car ;
you create a reference (called car) of compile-time type TickInterface. This means that the compiler will only let you call 
car.tick();
(because the compiler knows car is of type TickInterface, and it knows TickInterface declares a method called tick()), but it will not let you do
car.refuel();
because not every TickInterface instance has a method called refuel().
When you assign a value to car with
car = new Car();
you are performing an upcast. The type of the expression on the right hand side of the = is Car, while the type of the expression on the left hand side is TickInterface. Since the compiler is assured that every Car instance is also a TickInterface instance, this is perfectly legal.
When you add car to your list:
rides.add(car);
you effectively create a second reference to the Car object you created. The second reference is kept internally in the List. Since you declared the list to be of type TickInterface, with
List<TickInterface> rides = new ArrayList<TickInterface>();
you can think of that hidden internal reference as being of compile-time type TickInterface as well.
However, there is no reason for both these references to be the same type. You can do
Car car = new Car();
Bicycle bicycle = new Bicycle();
LoopClass(){
    ArrayList<TickInterface> rides = new ArrayList<TickInterface>();
    rides.add(car);
    rides.add(bicycle);
void thisLoopsEveryFrame(){
    for(TickInterface ride : rides){
        ride.tick();
    }
}
Now car has compile-time type Car (and bicycle has compile-time type Bicycle). The call
rides.add(car);
is perfectly legal: rides.add(...) is expecting something of type TickInterface, and you are giving it a Car: the compiler again is assured that every Car instance is also an instance of TickInterface. In this version, you have moved the upcast to this point in the code, instead of to the assignment to car.
Now, because the compile-time type of car is Car, the method you wanted to write:
void refuelCar(){
    car.refuel(); 
}
will compile and execute just fine.