Инкапсуляция VS наследование - как использовать защищенную функцию?

В языках ООП, таких как C# или VB.NET, если я создаю свойства или методы в суперклассе protected, я не могу получить к ним доступ в своей форме - к ним можно получить доступ только в моем классе, который наследуется от этого суперкласса.

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

Как правильно это сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
3 284
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Это немного похоже на высказывание, что у меня есть Автомобиль (Автомобиль) с защищенным рулевым колесом, поэтому я не могу получить к нему доступ. Машина мне ни к чему.

Либо сделайте эти члены общедоступными (или, по крайней мере, внутренними) и используйте их, либо откажитесь от класса и используйте тот, который дает вашему потребляющему коду функции, которые ему нужны.

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

Извините, не совсем понятно, что вы имеете в виду под словом «в моей форме» - какова связь между вашей формой и двумя классами? Если ваши классы являются элементами управления в одном проекте и вы хотите получить доступ к свойствам из формы, вы должны использовать ключевое слово «internal».

Ответ принят как подходящий

"необходимо сделать их общедоступными, что препятствует инкапсуляции"

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

Вот что важно. Инкапсуляция не означает сокрытие. Защищенные и частные не являются важной частью хорошей инкапсуляции. Вы можете делать хороший дизайн, когда все будет публично (например, так работает Python).

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

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

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

  1. Определите метод как «protected», «internal» или «private». В первом случае метод экземпляра будет использоваться только внутри методов производного класса того же экземпляра; во втором случае все классы в сборке будут иметь доступ к этим методам, а внешние классы - нет; в третьем случае никакие внешние классы, даже производные в той же сборке, не будут иметь доступа, если их код не вложен в объявляющий класс.
  2. Определите метод как `public`, но пусть классы, которые создают экземпляры, сохраняют их частными и никогда не открывают внешнему миру. Любой, кто хочет вызвать метод экземпляра для объекта, должен иметь экземпляр для его вызова. Если класс содержит экземпляры, но никогда не предоставляет прямых ссылок на них, единственными методами экземпляра, которые могут когда-либо использоваться для этих экземпляров, будут те, которые классы-хранилища используют сами.
  3. Определите метод как `public`, но у него есть конструктор, который принимает место, в котором могут храниться один или несколько делегатов частных методов. Код, имеющий доступ к этим делегатам, сможет вызывать методы, упомянутые в нем, но другой код не будет (кроме использования Reflection способами, которые, как мне кажется, можно использовать только в сценариях с полным доверием).

Если Reflection в сценариях с неполным доверием позволит привязывать несвязанные делегаты к произвольным экземплярам объектов, можно использовать вложенные классы для усиления №3, чтобы получить доступ к полям private для получения незаконного доступа к функциям private; это определенно было бы запрещено вне сценариев полного доверия.

Другие вопросы по теме