Quando você declara uma variável, você define seu tipo e depois a instancia. A construtor usado para a instanciação pode ser construtor de qualquer subclasse do tipo definido.
Pense no seguinte: sempre que você definir o tipo mais genérico, você pode instanciá-lo de forma específica. Exemplos:
Objectfrase="Olá mundo";// uma String é um Object, portanto isso é válidoList<Integer>lista=newArrayList<Integer>();// ArrayList é um List; OK!
Agora, se dois objetos tem uma superclasse em comum não necessariamente é possível fazer cast:
Beansb=newBeans();// a classe java.beans.Beans é subclasse direta de ObjectCalendarc=Calendar.getInstance();aclassejava.util.Calendartambémb=c;// isso não presta!
Por fim, o cast é possível de um supertipo para um subtipo, desde que tenha-se certeza que o objeto é uma instância da subclasse: