lime is a Fruit reference to a Citrus object. The only object I see being created is the explicit Citrus one (it's possible that println() creates some objects behind the scenes, but I don't think you're asking about those.)
To say the same thing in a lot more words ... you have a variable declared with type Fruit. A variables that holds an object is really just a pointer, a little bit of information about where to find an object in memory. A variable like lime is allowed to point to an object exactly matching the declaration (Fruit) or any subclass (Citrus). When you call lime.method() you run the method on the actual object, whether it is Fruit or Citrus. We often say the derived class "is a" base class, or "Citrus is a Fruit". That's not always 100% true but as a general concept it tells us we can make a variable of type Fruit point to an object of type Citrus because for this purpose a Citrus is a Fruit. Hope that helped. Objects are tons of fun, no?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi