Сделать родительский класс Java не частью интерфейса - PullRequest
4 голосов
/ 12 июня 2010

(Это гипотетический вопрос для обсуждения, у меня нет реальной проблемы).

Скажем, что я делаю реализацию SortedSet, расширяя LinkedHashMap:

class LinkedHashSortedMapThing extends LinkedHashMap implements SortedSet {
 ...
}

Теперь программисты, которые используют этот класс, могут делать

LinkedHashMap x = new LinkedHashSortedMapThing();

Но что, если я считаю расширение LinkedHashMap деталью реализации, и не хочу, чтобы оно было частью контракта класса?Если люди используют строку выше, я больше не могу свободно изменять эту деталь, не беспокоясь о нарушении существующего кода.Есть ли способ предотвратить подобные вещи, кроме предпочтения композиции перед наследованием (что не всегда возможно из-за частных / защищенных членов)?

Ответы [ 4 ]

11 голосов
/ 12 июня 2010

Я думаю, что самым простым способом было бы создать закрытый внутренний класс, который расширяет LinkedHashMap, и LinkedHashSortedMapThing сохраняет ссылку на него и указывает все его методы там.

7 голосов
/ 12 июня 2010

Если вы расширяете класс, вы наследуете его открытый интерфейс, и нет способа избежать этого AFAIK.Композиция была бы действительно выгодным решением, так как вы все равно не должны зависеть от внутренних компонентов LinkedHashMap - они также могут измениться в будущих версиях JDK.

У Java нет частного наследования, как в C ++в любом случае практически более или менее эквивалентно композиции).

0 голосов
/ 12 июня 2010

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

Если вам нужен защищенный доступ к функциональности LinkedHashMap, используйте закрытый внутренний класс в качестве члена делегирования.

0 голосов
/ 12 июня 2010

Вы можете реализовать SortedSet путем агрегации, чтобы открытый интерфейс класса не включал LinkedListHashMap

class LinkedHashSortedMapThing extends AbstractSet implemenents SortedSet
{
    LinkedListHashMap map;


    public int size() {
       return map.size();
    }
}
...