Исключение и наследование в Java

Предположим, у нас есть эта проблема

public class Father{
    public void method1(){...}
}

public class Child1 extends Father{
    public void method1() throws Exception{
    super.method1();
    ... 
    }

}

Child1 продолжаетсяFather и переопределяетmethod1 но учитывая реализациюChild1.method1 теперь выбрасывает исключение. Это не скомпилируется, так как переопределяющий метод не может генерировать новые исключения.

Какое лучшее решение?

Распространить требуемое исключение наFather, Для меня это против инкапсуляции, наследования и общего ООП (Father потенциально выдает исключение, которое никогда не произойдет).ИспользоватьRuntimeException вместо? Это решение не будет распространятьException кFather, но документы Oracle и другие источники утверждают, что класс исключений следует использовать, когда «код клиента ничего не может сделать». Это не тот случай, это исключение будет полезно для восстановления блаблабла (почему это неправильно использоватьRuntimeException вместо?).Другие..
 chamba19 окт. 2012 г., 19:38
спасибо, что поделились своими мыслями с людьми, теперь я более или менее знаю, что мне нужно делать в следующий раз, когда я найду такую проблему

Ответы на вопрос(5)


Вот почему метод в дочернем классе не является переопределением метода родительского класса.

капсуляции, наследования и общего ООП (отец может бросить и исключение, которое никогда не произойдет)

Au contraire: этохороший OO. Изображение стороны звонящего:

Father f = factory.getSomeImplementation();
f.method1();
// user has no chance to see the `Exception` of Child coming...

Фабрика может вернуть экземплярFather или жеChild или что-то совершенно другое, какBrother, Но контрактmethod1 должны быть одинаковыми ввсе случаев. И этот контракт включает в себя проверенные исключения. Это принцип подстановки Лискова, одно из основных правил ОО.

Так что, если исключение является частью делового контрактаmethod1 это должно быть объявлено в корне. Если это не так (например, простая проверка аргументов), тогдаRuntimeException маршрут, по которому нужно идти (т. е. даже без наследования).

Если метод суперкласса не объявляет исключение, то переопределенный метод подкласса не может объявить проверенное исключение, Таким образом, вы можете использовать только непроверенное исключение.

Другой вариант - разрешить объявлять суперклассParentException а затем дочерние переопределенные методы могут объявлять любые исключения, которые являются дочернимиParentException

что выдает исключение в Child1. Если есть некоторые предварительные условия и т. Д., Вы всегда можете использовать любой из подклассов RuntimeException, например IllegalArgumentException.

Однако, если есть какое-то CheckedException, то логика подсказывает, что вы должны обработать его самим этим методом и создать сообщение другим способом.

Я думаю, что общее правило таково, что

если вы знаете, как с этим справиться .. используйте проверенное исключение, иначе непроверенное исключение

Решение Вопроса

и она работает довольно хорошо. Если вы реализуете приложение, вероятно, используйте это решение.

Однако, если вы реализуете библиотеку, которая предоставляет API IMHO, вы должны использовать проверенное исключение. В этом случае вы должны создать собственное исключение, напримерBaseException, методmethod() изFather бросит это. ОпределениеChildException extends BaseException и объявитьmethod1() детского класса, чтобы бросить его.

Это не нарушает инкапсуляцию: базовый класс генерирует базовое исключение. Он не имеет никакого представления о конкретном исключении. Дочерний класс генерирует конкретное исключение, которое, однако, расширяет базовое исключение и поэтому может рассматриваться клиентским кодом как базовое исключение.

В качестве примера могу привестиIOException а такжеFileNotFoundException это расширяет его. Вы можете работать с перехватом входного потокаIOException в то время как бетонный потокFileInputStream и это бросаетFileNotFoundException, Но клиент этого не знает. ЛовитIOException.

 chamba19 окт. 2012 г., 19:03
да, я понимаю, я просто не чувствовал себя комфортно, добавляя броски к Отцу, мне не нравится идея, что Отец добавляет что-то, потому что это требует Ребенок. Спасибо!!

Ваш ответ на вопрос