Все классы наследуются от Object. Объект имеет строку toString.
Чтобы использовать любой интерфейс, он должен быть поддержан реальным классом. Таким образом, компилятор Java знает, что он может использовать любой метод, определенный в java.lang.Object при работе с интерфейсом.
Проще говоря, немного по-другому:
interface I { ... }
имеет "магию"
interface I extends Object { ... }
Таким образом, вы можете использовать методы Objects при детализации с I. Однако вы не можете использовать любые методы в конкретном классе, которые не отображаются в интерфейсе. Итак, чтобы объединить два примера:
interface Car {
void drive();
}
class Convertible implements Car {
void drive() {}
void openRoof() {}
public static void main() {
Car porscheBoxster = new Convertible();
porscheBoxster.drive(); // OK - exists in interface
porscheBoxster.toString(); // OK - exists in java.lang.Object.
porscheBoxster.openRoof(); // Error. All we know is the porscheBoxster is of type Car.
// We don't know if it is a Convertible or not.
}
}