Скрытие данных – одна из важных особенностей объектно-ориентированного программирования, которая позволяет запретить функциям программы напрямую обращаться к внутреннему представлению класса. Ограничение доступа к членам класса определяется разделами внутри тела класса, помеченными словами public, private, и protected. Ключевые слова public (открытый), private (закрытый) и protected (защищённый) называются спецификаторами доступа.
Класс может иметь по нескольку разделов, помеченных как public, protected, или private. Каждый раздел остаётся в силе до тех пор, пока не появится метка другого раздела или правая скобка, закрывающая тело класса. По умолчанию доступ для членов классов является открытым (public).
class Base { public: // открытые члены класса расположены здесь protected: // защищённые члены класса расположены здесь private: // закрытые члены класса расположены здесь };
Член класса со спецификатором public доступен из любого места вне класса, но в рамках программы. Вы можете присваивать и получать значение открытых переменных без использования какой-либо функции-члена, как показано в следующем примере:
import std.stdio; class Line { public: double length; double getLength() { return length ; } void setLength( double len ) { length = len; } } void main( ) { Line line = new Line(); // установить длину линии line.setLength(6.0); writeln("Длина линии : ", line.getLength()); // установить длину линии без использования фунции-члена line.length = 10.0; // Допустимо, т.к. length объявлена как public writeln("Длина линии : ", line.length); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Длина линии : 6 Длина линии : 10
К члену класса со спецификатором private нельзя получить доступ или даже просмотреть его извне класса. Только члены класса и дружественные функции могут иметь доступ к закрытым членам.
Практически вам нужно определить данные в разделе private, а связанные с ними функции в разделе public, чтобы их можно было вызывать извне класса, как показано в следующей программе.import std.stdio; class Box { public: double length; // Определения функций-членов double getWidth() { return width ; } void setWidth( double wid ) { width = wid; } private: double width; } // Главная функция программы void main( ) { Box box = new Box(); box.length = 10.0; writeln("Длина коробки : ", box.length); box.setWidth(10.0); writeln("Ширина коробки : ", box.getWidth()); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Длина коробки : 10 Ширина коробки : 10
Очередное нудное уточнение. Правила доступа к членам класса со спецификатором private, описанные в этом разделе,
на самом деле действуют в языке C++. А в языке D доступ к таким членам открыт из любого места в модуле,
в котором объявлен этот класс. Для функций из других модулей доступ действительно закрыт.
Так что в приведённом выше примере вполне можно написать в последней строке:
writeln("Ширина коробки : ", box.width);
– прим. пер.
Переменная или функция-член со спецификатором protected очень похожа на закрытый член (private), но она предоставляет ещё одно преимущество, в соответсвии с которым к ним имеется доступ в производных классах.
Вы изучите производные классы и наследование в одной из следующих глав. На данный момент вы можете проверить следующий пример, когда один производный класс SmallBox унаследован от родительского класса Box.
Следующий пример аналогичен приведенному выше примеру, и здесь член width доступен из любой функции-члена производного класса SmallBox.
import std.stdio; class Box { protected: double width; } class SmallBox:Box { // SmallBox - это производный класс. public: double getSmallWidth() { return width ; } void setSmallWidth( double wid ) { width = wid; } } void main( ) { SmallBox box = new SmallBox(); // установить ширину коробки с использованием функции-члена box.setSmallWidth(5.0); writeln("Ширина коробки : ", box.getSmallWidth()); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Ширина коробки : 5
И ещё добавлю, что кроме трёх рассмотренных в этом разделе, в языке D также существуют ещё два спецификатора доступа:
package – доступ на уровне пакета, и export – доступ извне программы, используется для
динамически связываемых библиотек.
– прим. пер.