Должен класс придерживаться документированного контракта интерфейса, который, как говорят, реализует этот интерфейс

Я знаю, что реализация интерфейса означает (технически), но я не уверен, понимаю ли я, что означает "контракт":

Предположим, что я делаю класс MyList, который реализует java.util.List (т.е. реализую все методы с компилируемым кодом), тогда MyList a List? ИЛИ мне нужно прочитать все комментарии методов, которые я переопределяю, и убедиться, что моя реализация выполняет эти "ожидания" от поведения?

Ответ 1

Технически, да, MyList является List, если он реализует все методы интерфейса List. Но компилятор не волшебник. Он не может проверить, что ваши методы делают то, что они должны делать. И, конечно, каждый метод должен делать то, что говорит его документация.

Если я получаю List, и этот List является экземпляром MyList, и я вызываю list.add("foo"), я ожидаю, что в конце списка будет добавлено "foo". Не удаляться, не добавляться дважды, или как-то иначе. Поэтому, конечно, если ваш класс реализует List, его методы должны соответствовать контракту, определенному в его документации по API.

Представьте, что вы продаете автомобили. Я иду в твой магазин и покупаю машину. Для меня это автомобиль, потому что он похож на все другие автомобили: у него есть колеса, педали, окна и т.д. Но если я нажимаю на акселератор, он тормозит, и когда я включаю свет, он идет, и когда я открываю окна, он ускоряется и убивает бедного ребенка на дороге, я не буду счастлив вообще, и у вас будут проблемы, потому что автомобиль, который вы продали мне, не ведет себя правильно.

Ответ 2

В Java разница между классом и интерфейсом заключается в том, что класс имеет реализации методов. Интерфейса нет. Таким образом, интерфейс может иметь метод add(), но ничего не говорит о том, как работает add. Класс должен будет определить, как работает add.

Вы реализуете интерфейс в момент, когда вы положили implements InterfaceName в определение класса. Затем вы должны определить все методы интерфейса, или ваше приложение не будет компилироваться. Тогда да, было бы правильно сказать, что MyClass - это MyInterface - вы даже можете перейти на MyInterface interface = new MyClass();

И да, вы должны прочитать все комментарии и убедиться, что ваш класс реализует интерфейс ожидаемым образом. В противном случае вы получите что-то, что компилируется, но может не работать правильно.

Ответ 3

Интерфейс является необходимым минимумом для контракта: как вы говорите, если он не компилируется, вы не можете выполнить контракт! Но язык, возможно, не сможет определить и ограничить полные требования интерфейса, поэтому вы также должны учитывать эти ожидания.

Одним простым примером является интерфейс ICloneable. Если все, что вы делаете, это реализовать

public MyObject clone() {
    return (MyObject)super.clone();
} // clone()

тогда вы выполнили контракт с языком и, возможно, ваш контракт с классом. Но если ваш класс содержит List, вы удивите своих пользователей: "Это не было clone() правильно!"

Контракт также включает ожидания пользователей. Разбейте их, и хотя адвокат языка может сказать, что ваш класс - a List, другие не согласятся.

Ответ 4

- список MyList?

Чтобы ответить на этот вопрос, вам нужно сначала понять, что делают интерфейсы или что они написаны для...

Не забывайте, что интерфейсы могут предложить вам очень важный отрыв между тем, что делает класс , и , как они это делают... поэтому технически реализация интерфейса не связана с запросом, если объект есть что-то, но больше о запросе того, как объект может что-то сделать

поэтому, когда вы указываете List myContainer = new ArrayList(); вы определяете объект, который может выполнять все, что может сделать список... добавлять, удалять, получать и т.д.

вы можете сказать, что это список, я бы сказал, что он может делать то, что может сделать список.