В Java 1.4 или более ранних версиях оба фрагмента не должны компилироваться.В версии 1.5 или более поздней должны компилироваться обе версии.
Если вы переопределяете метод в Java 1.4, вы должны предоставить точно такой же тип возвращаемого значения, что и метод базового класса.
Это ограничение было снятов Java 1.5 и более поздних версиях здесь разрешено предоставлять тип возвращаемого значения, который наследуется от возвращаемого типа метода базового класса.
Это имеет смысл и может быть полезным.Если у вас есть:
I1 x = new I12Impl();
, то все, что вы знаете, это то, что xm () возвращает I1.
Но если у вас есть немного больше информации:
I12 x = new I12Impl();
, тогдавы знаете, что xm () возвращает I12 (который также является I1).
Иногда это может быть удобно (например, вы можете избежать потери при вызове xm ())