yes, the compiler should reuse the existing method. A Object version will still exist, it only is a bridge to the real implementation, the covariant method. The JVM only cares about an existing Object method, because there is an interface with that method and the method must be implemented. But the JVM allows multiple methods of the same name with the same parameter types and different return types. When you for example compile a class with a method String invokeMet(), and the parent class contains a method Object invokeMe, then we have the covariant case here and the compiler will not only add the method String invokeMe() as specified by the user, the compiler will also add a bridge method for Object invokeMe() that will call the String returning method. From this logic the constraints of covariants do also become clear... the overriding method must return a class, that is a subclass of the other method return type. String is ok for Object, but obviously not for Integer.
Now our policy for methods from GroovyObject is, that they are only added if needed. If the super class is already implementing them, then don't override. If the user has specified them, then don't replace. According to this, the compiler must not add another getProperty method, because Properties has already one. If that is not doing the right thing, then the method needs to be overridden by user code.
So I compare this case more to your Child class without any user methods... which should compile and cause the compiler to add the bridge method.