Let's see...
First, the idea of covariant data type on return exists only when you are overriding methods. If you have two methods with different types of arguments, the two methods are different ones... as you said, its an overloading. So, it doesnt matter if String extends Object... they are not covariant in this context.
Now what do we have:
SuperClass: Object get (Object){return "super";}
SubClass: String get (String){return "sub";}
SuperClass superC;
SubClass subC;
When we have overriding, through polimorfism, at runtime the code that will run is that of the type of the actual object. But as we have an overloading, at runtime the code that will run is that of the type of the variable. So, as the type of the variable is SuperClass, what runs is the version of SuperClass get() method.
Now let's make some adjustments at your code to make things more complicated:
if the type of the argument in subclass was Object, then we would have overriding and you try to run the same code with new adjustments, you may note the same results would be:
superclass version
subclass version
[ July 04, 2007: Message edited by: Rafael Souza ]