Контракт типа (class, interface, enum) - это, ну, контракт , который этот тип обещает соблюдать. В нем говорится:
- какие параметры допустимы для конструктора и / или методов этого типа;
- что вы должны и / или не должны ожидать, что этот тип будет делать. Например, в нем может быть указано, что вы должны ожидать, что этот класс будет поточно-безопасным или не поточно-безопасным;
- Какие инварианты поддерживаются этим типом. Например, метод типа
addData(float)
класса MathAverage
, который вычисляет среднее значение его входных данных, может указывать, что каждый раз, когда ваш вызов add(float)
возвращается, вы должны ожидать вызова MathAverage.getAverage()
, чтобы вернуть правильное среднее значение текущего ввода.
- Вообще говоря, ваш тип может указывать любое ограничение, которому должны следовать все его подтипы. Например, он может сказать «ни один метод этого типа не должен выполняться дольше 1 секунды».
Контракт указан в произвольной форме в javadoc типа. Существуют некоторые инструменты / методы для обеспечения исполнения контрактов, но они ограничены именно потому, что контракт может быть произвольным или даже противоречивым в случае ошибки программиста.
Поскольку подтип (подкласс) может расширять / изменять поведение методов супертипа произвольным образом, он также может нарушать некоторые части контракта супертипа. Примером этого может быть расширение HashMap
, которое принимает значения null
и ключи, с некоторой реализацией, которая запрещает значения null
при вызовах его методов.
Другим важным аспектом контракта типа является то, что подтип может иметь более сильный контракт (охватывающий подмножество ограничений в контракте типа), но не может иметь более слабый контракт (охватывающий супернабор ограничений в контракте типа).
Например, если метод вашего типа «doX (n)» обещает занять O(n)
(линейное) время, «doX (n)» в подтипе может занять O(1)
(постоянное) время, но не может занять O(n^2)
время .