Cuando creas a Funcionario jose = new Contador(); a simple vista estas creando un Contador y si, pero lo haces dentro de una variable de tipo Funcionario, la diferencia radica en que ambos tendran acceso a los metodos de la clase Funcionario, pero Funcionario jose = new Contador(); no tendra acceso a los metodos de la clase contador de forma directa, pero si puedes acceder a ellos haciendo un casting (recordaras cuando se dijo de decirle a java que aunque sea un double lo tome como un int, pos es basicamente lo mismo) tal que asi: ((Contador)jose).getSalario(); //por ejemplo
- Esto por ser una instancia de Funcionario, esto del cast solo es necesario con los metodos exclusivos del contador.
Pero para los metodos que coinciden en ambas clases, los afectados por el polimorfismo, osea los @Override, en esos casos, aunque sea una referencia de Funcionario, los metodos que llames serán los implementados en la clase Contador (es decir que ese metodo se comportara como lo dicte la clase contador), solo los metodos polimorficos si no estoy mal, esos si puedes llamarlos directamente.
En cuanto a la utilidad, lo que me dicta la logica es que esto nos da la posibilidad de que le cambiemos de clase a voluntad.
Creo que tambien veremos un poquito mas de su utilidad con las interfaces.