Nano Hash - криптовалюты, майнинг, программирование

Наследование нарушает инкапсуляцию

Я видел много статей, где говорится, что наследование нарушает инкапсуляцию.

http://igstan.ro/posts/2011-09-09-how-inheritance-violates-encapsulation.html

Но я не могу понять концепцию, стоящую за этим. в данном примере

Может ли кто-нибудь объяснить, как композиция позволяет избежать этой проблемы


  • Обернутый HashSet вызывает свой собственный add, а не add обертки. 29.10.2016

Ответы:


1

В примере в статье, на которую вы ссылаетесь:

     set.addAll(Arrays.asList("Snap", "Crackle", "Pop"));

Это вызывает InstrumentedHashSet.addAll.

InstrumentedHashSet.addAlladds 3 to the counter, then callsHashSet.addAll`.

HashSet.addAll вызывает this.add три раза, чтобы добавить каждый из элементов.

Но this.add на самом деле является призывом к InstrumentedHashSet.add !

Каждый вызов InstrumentedHashSet.add добавляет 1 к счетчику и вызывает super.add.

Каждый вызов HashSet.add выполняет фактическую работу по добавлению элемента в набор.

Конечным результатом является то, что мы добавили к счетчику 6, а не 3, как можно было бы ожидать.

Для правильной реализации InstrumentedHashSet необходимо знать, как реализован HashSet.addAll, и НЕ увеличивать счетчик в addAll. Но это знание нарушает инкапсуляцию. Подклассу не нужно знать, как реализован его суперкласс.


Может ли кто-нибудь объяснить, как композиция позволяет избежать этой проблемы

Он избегает этого, потому что когда HashSet.addAll вызывает this.add, эти вызовы this.add не являются вызовами InstrumentedHashSet.add. Это прямые звонки HashSet.add.

На самом деле, при условии, что HashSet.addAll реализует контракт Set.addAll, InstrumentedHashSet не имеет значения, как он реализован. Здесь нет нарушения инкапсуляции.

29.10.2016

2

Я видел много статей, где говорится, что наследование нарушает инкапсуляцию.

http://igstan.ro/posts/2011-09-09-how-inheritance-violates-encapsulation.html

Но я не могу понять концепцию, стоящую за этим. в данном примере

Может ли кто-нибудь объяснить, как композиция позволяет избежать этой проблемы

Слово «разрыв» может быть слишком сильным, но наследование, безусловно, по крайней мере ставит под угрозу инкапсуляцию.

Важной целью инкапсуляции является отделение реализации API от его контракта. Другими словами, клиенты, желающие использовать API, должны понимать только его «правила поведения» (т. е. его контракт) без необходимости знать что-либо о том, как он работает внутри. Это позволяет модулям больших систем отделяться и развиваться независимо (до тех пор, пока контракт остается нетронутым).

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

Есть два распространенных способа, которыми это может произойти:

  • Если подкласс использует метод, унаследованный от базового класса, и этот метод вызывает другой метод, который является частью экспортированного API (так называемое «самостоятельное использование» методов API). Во избежание ошибок автору подкласса необходимо знать о самостоятельном использовании методов базовым классом. Это деталь реализации, о которой клиенту API в противном случае не нужно было бы знать.

  • Защищенные члены. Иногда подкласс не может реализовать функцию без доступа к данным или поведению родительского класса. Java предоставляет тип доступа protected для обеспечения доступа к членам по подклассам. Таким образом, подкласс получает прямой доступ к информации и методам, которые в противном случае были бы инкапсулированы в родительском классе. Таким образом, подкласс становится зависимым от деталей реализации родителя.

Недостатком утечки сведений о реализации из вашего класса является то, что правильное его использование больше не зависит только от контракта API. Всякий раз, когда реализация меняется, есть шанс, что подклассы сломаются.

29.10.2016
  • +1. Однако я немного не согласен с вами по поводу терминологии: я бы сказал, что если правильное создание подклассов зависит от определенного поведения, то на самом деле это поведение является частью контракта класса, а не просто деталь реализации. Но это трудно сделать правильно; намного проще (и естественнее) определить контракт для клиентов класса, чем для его подклассов. 29.10.2016
  • Я бы сказал, что если правильное создание подклассов зависит от определенного поведения, то на самом деле это поведение является частью контракта класса, ... без аргументов. Ключевым моментом здесь является то, что независимо от того, было ли это задумано или нет, поведение становится частью экспортируемого API. 29.10.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..