Почему языки ооп не поддерживают отдельные модификаторы доступа для чтения и записи?

#oop #language-design #design-principles

#ооп #язык-дизайн #принципы проектирования

Вопрос:

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

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

Ну, компиляторы могут оптимизировать вызов функции и встроить назначение, но это то, что вы не можете контролировать. Даже ключевое слово inline в c — это всего лишь подсказка, и компиляторы могут ее игнорировать. Вы должны предположить, что вызывается функция, и это будет медленнее.

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

Какие проблемы возникли бы, если бы мы могли установить разные модификаторы доступа для записи и чтения (например, как это делают файловые системы), кроме простого указания, что это нарушило бы догматический принцип инкапсуляции?

Комментарии:

1. (Должно быть community wiki, но я не нахожу, где я могу это установить.)

2. Что-то связанное с вмешательством в полиморфизм, но я не могу сформулировать это в виде достаточно связного ответа для публикации.

3. Они действительно поддерживают это. Они просто реализуют это в терминах специального метода, называемого свойством .

Ответ №1:

Но вы можете создавать свойства с разным доступом для средства получения и установки в C#:

 public int Foo {
    get { return foo; }
    protected set { foo = value; }
}

protected int Bar { get; private set; }
  

Первый создает свойство «Foo» с общедоступным средством получения и защищенным средством установки, в то время как второй создает свойство «Bar» с защищенным средством получения и частным средством установки.

Что касается Objective-C, языка, специально предназначенного для общего случая («общедоступный» способ получения, «частный» способ установки), позволяя вам объявлять свойство readonly , а затем повторно объявлять его readwrite в расширении класса или подклассе.

Какие еще языки вы имеете в виду?

Комментарии:

1. Я надеюсь, что компилятор сможет встроить эти свойства.