При реализации метода в дочернем классе вы можете скрыть или выбросить исключения, которые «расширяют» исключение из базового класса.
В вашем случае:
public void doSomething() {
throw new IOException(); // this does not compile since ISomething1.doSomething does not declare a throws clause
}
IOException не является исключением времени выполнения и должно быть объявлено в сигнатуре метода.
Но это:
public void doSomething() throws IOException {
throw new IOException(); // this does not compile since ISomething1.doSomething does not declare a throws clause
}
не подчиняется описанным правилам и недействительно из-за
interface ISomething1 {
void doSomething();
}
P.S. Это не разные подписи.
Если вы хотите создать новое исключение и расширить оба интерфейса - вы можете инкапсулировать IOException следующим образом:
throw new RuntimeException(new IOException());
UPDATE
Но это опасно, поскольку пользователь класса (программист) не обязан перехватывать это исключение, и это может нарушить работу конечного пользователя.