Открытые и закрытые члены класса, модификаторы доступа

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

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

Для управления доступом используются модификаторы. Также приводятся рекомендации по организации доступа.

Доступ к членам класса

Доступ к открытому члену свободно осуществляется из кода, определенного за пределами класса. А закрытый член класса доступен только методам, определенным в самом классе. С помощью закрытых членов и организуется управление доступом.

Ограничение доступа к членам класса является основополагающей идеей объектно-ориентированного программирования, поскольку позволяет исключить неверное использование объекта.

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

Для закрытого члена класса нельзя задать значение непосредственно в коде за пределами класса. Но в то же время можно полностью управлять тем, как и когда данные используются в объекте.

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

Модификаторы доступа

Управление доступом в языке C# организуется с помощью четырех модификаторов доступа: public, private, protected и internal.

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

Когда же член класса обозначается спецификатором private, он может быть доступен только другим членам этого класса. Следовательно, методы из других классов не имеют доступа к закрытому члену (private) данного класса.

Если ни один из спецификаторов доступа не указан, член класса считается закрытым для своего класса по умолчанию. Поэтому при создании закрытых членов класса спецификатор private указывать для них необязательно.

С помощью модификатора доступа protected обеспечивается создание защищенного члена класса, доступ к которому открыт в пределах иерархии классов (в классах-наследниках).

А модификатор internal служит в основном для сборок.

Для наглядности давайте рассмотрим пример:

 // Открытые и закрытые члены класса ABCD
   using System;
   namespace ConsoleApplication1
   {
      class ABCD 
      {
         public int a;       // Открытый член 
         private int b;      // Закрытый член, указанный явно 
         int c;              // Закрытый член по умолчанию
         protected int d;    // Закрытый член, указанный явно
         public ABCD()       // Конструктор
         { 
         }        
         public ABCD(int x, int y, int z, int w)  // Другой конструктор
         { 
            a = x;
            b = y;
            c = z; 
            d = w;
         }
         // метод класса - вывод полей
         public void rewrite() 
         { 
            Console.WriteLine("Поля класса: {0}  {1}   {2}   {3}", a,b,c,d); 
         }
      } 
      class Program 
      { 
         static void Main()
            {
               ABCD obj1 = new ABCD();   // Первый объект
               obj1.a = 5; 
               // obj1.b = 8;      // Данные операции недопустимы, 
               // obj1.c = 13;     // так как в классе Program  
               // obj1.d = 21;     // поля закрыты для доступа
               obj1.rewrite(); 
               ABCD obj2 = new ABCD(5, 8, 13, 21);   // Другой объект
               obj2.rewrite(); 
               Console.ReadKey();
            }
         } 
      }       // конец примера

Комментарии. Создается некоторый класс ABCD с 4 полями (a,b,c,d), с двумя конструкторами и одним методом rewrite( ). В методе Main( ) класса Program инициализируются разными конструкторами два объекта класса ABCD – obj1 и obj2. Для каждого объекта вызывается его метод rewrite().

Результат выполнения программы:

32
Как мы видим, первый конструктор обнуляет все поля объекта obj1 (поле a изменяется после выполнения операции obj1.a=5, так как это поле объявлено как public).

Выполнение оператора obj1.b = 8; приведет к ошибке: «ConsoleApplication1.ABCD.b» недоступен из-за его уровня защиты. Как видите, доступ к членам b, c и d закрыт, но, несмотря на это, свободный доступ к ним организован с помощью public-конструктора c параметрами и public-метода rewrite( ).

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

Организация закрытого и открытого доступа

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

1. Члены, используемые только в классе, должны быть закрытыми.

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

3. Если изменение члена приводит к последствиям, распространяющимся за пределы области действия самого члена, то есть оказывает влияние на другие аспекты объекта, то этот член должен быть закрытым, а доступ к нему — контролируемым.

4. Члены, способные нанести вред объекту, если они используются неправильно, должны быть закрытыми. Доступ к этим членам следует организовать с помощью открытых методов, исключающих неправильное их использование.

5. Методы, получающие и устанавливающие значения закрытых данных, должны быть открытыми.

6. Переменные экземпляра допускается делать открытыми лишь в том случае, если нет никаких оснований для того, чтобы они были закрытыми.

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

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Пролистать наверх