Вы, вероятно, ожидаете, что поля будут переопределены, как метод, с динамической диспетчеризацией на основе типа времени выполнения объекта.
Это не так, как работает Java. Поля не переопределяются, они скрыты. Это означает, что объект класса B имеет два поля с именем "s", но к какому из них обращаются, зависит от контекста.
Что касается того, почему это так: не имеет смысла переопределять поля, поскольку нет никакого полезного способа заставить его работать, когда типы различаются, и просто нет смысла, когда тип такой же (как вы можно просто использовать поле суперкласса). Лично я думаю, что это просто ошибка компилятора.