Почему нет методов у потомков?
Пора мне попрактиковаться в преподавательской деятельности:
Итак, рассмотрим пример. При объявлении переменной мы перед собой видим следующую структуру:
Figure f1 = new Rect(1,2);Figure  в этом выражении представляет из себя то, что можно записать в переменную f1, но кроме этого оно символизирует то, как мы воспринимаем эту переменную. Другими словами, что бы мы туда не записали, воспринимать мы будем ее как Figure и видеть методы присущие только этому классу. (Стоит заметит, пусть даже методы мы видим только от родительского класса, но если мы их переопределим, выполнятся будет именно новая версия).
Аналогичная ситуация и со списками. Какой класс ты поставишь в <>, так и будет восприниматься содержимое этого списка. 
Если тебе нужно добраться до невидимых методов, можно сделать 2 вещи:
Line f2 = (Line)f.get(0);
Или ((Line)f.get(0)).move();
Но вот тут:
f.add(new Line(1,2));
System.out.print(f.get(0).getName()) // почему-то печатает "Figure"
Ты сударь что-то брешешь. Он должен должен и будет выводить 'Line'. И не надо говорить что у тебя не так. Проверяй, что туда записываешь и как переопределен у тебя этот метод.
Напиши @Override в потомках над методами которые переопределяешь.  Для видимости метода которого нет в родителе нужно приводить тип типа
Line f1 = (Line) f.get(1); f1.move();