No, non è inutile. Avere un array di tipo Persona[] (indipendentemente dal fatto che Persona sia abstract o no) permette di sfruttare il polimorfismo, ma anche addirittura un array di tipo Tassabile[] sarebbe corretto se l'intenzione è quella di "vedere" gli oggetti solo come "tassabili" cioè solo per usare i metodi di Tassabile.
codice:Persona[] persone = new Persona[3]; persone[0] = new Studente( ..... ); persone[1] = new Lavoratore( ..... ); persone[2] = new Studente( ..... );
Questo è perfettamente lecito. Se invochi un persone[indice].aliquotaFiscale(), verrà eseguito il "giusto" metodo aliquotaFiscale per l'oggetto realmente istanziato che si trova a quell'indice dell'array.
E il fatto che Persona abbia un comportamento (i metodi) tutto "concreto" rende l'uso di abstract poco sensato.
Sì ma ripeto: stai usando un qualche libro o stai andando un po' a "tentativi" ?