Хотя приведенный выше пример, вероятно, указывает, что что-то идет не так, само NotImplementedException не всегда неверно. Это все о контракте суперкласса и о подклассе, реализующем этот контракт. Если у вашего суперкласса есть такой метод
// This method is optional and may be not supported
// If not supported it should throw NotImplementedException
// To find out if it is supported or not, use isAddItemSupported()
public void AddItem(double a, int b){...}
Тогда, не поддерживая этот метод, все еще в порядке с контрактом. Если это не поддерживается, вам, вероятно, следует отключить соответствующее действие в пользовательском интерфейсе. Так что, если вы согласны с таким контрактом, то подкласс реализует его правильно.
Другой вариант, когда клиент явно заявляет, что он не использует все методы класса и никогда не будет использовать. Как это
// This method never modifies orders, it just iterates over
// them and gets elements by index.
// We decided to be not very bureaucratic and not define ReadonlyList interface,
// and this is closed-source 3rd party library so you can not modify it yourself.
// ha-ha-ha
public void saveOrders(List<Order> orders){...}
Тогда можно перейти к реализации List, которая не поддерживает добавление, удаление и другие мутаторы. Просто документируйте это.
// Use with care - this implementation does not implement entire List contract
// It does not support methods that modify the content of the list.
public ReadonlyListImpl implements List{...}
Хотя ваш код для определения всего вашего контракта хорош, так как он позволяет вашему компилятору проверять, нарушаете ли вы контракт, иногда это нецелесообразно, и вам приходится прибегать к плохо определенным контрактам, таким как комментарии.
Короче говоря, возникает вопрос: действительно ли вы можете безопасно использовать свой подкласс в качестве суперкласса, принимая во внимание, что суперкласс определяется его контрактом, который является не только кодом.