Доступ к членам класса
48C# --- Руководство по C# --- Доступ к членам класса
Поддержка свойства инкапсуляции в классе дает два главных преимущества. Во-первых, класс связывает данные с кодом. И во-вторых, класс предоставляет средства для управления доступом к его членам. Именно эта, вторая преимущественная особенность и будет рассмотрена в данной статье.
В языке C#, по существу, имеются два типа членов класса: открытые и закрытые, хотя в действительности дело обстоит немного сложнее. Доступ к открытому члену свободно осуществляется из кода, определенного за пределами класса. А закрытый член класса доступен только методам, определенным в самом классе. С помощью закрытых членов и организуется управление доступом.
Ограничение доступа к членам класса является основополагающим этапом объектно-ориентированного программирования, поскольку позволяет исключить неверное использование объекта. Разрешая доступ к закрытым данным только с помощью строго определенного ряда методов, можно предупредить присваивание неверных значений этим данным, выполняя, например, проверку диапазона представления чисел. Для закрытого члена класса нельзя задать значение непосредственно в коде за пределами класса. Но в то же время можно полностью управлять тем, как и когда данные используются в объекте. Следовательно, правильно реализованный класс образует некий "черный ящик", которым можно пользоваться, но внутренний механизм его действия закрыт для вмешательства извне.
Модификаторы доступа
Управление доступом в языке C# организуется с помощью четырех модификаторов доступа: public, private, protected и internal.
Когда член класса обозначается спецификатором public, он становится доступным из любого другого кода в программе, включая и методы, определенные в других классах. Когда же член класса обозначается спецификатором private, он может быть доступен только другим членам этого класса. Следовательно, методы из других классов не имеют доступа к закрытому члену (private) данного класса. Eсли ни один из спецификаторов доступа не указан, член класса считается закрытым для своего класса по умолчанию. Поэтому при создании закрытых членов класса спецификатор private указывать для них необязательно.
С помощью модификатора доступа protected обеспечивается создание защищенного члена класса, доступ к которому открыт в пределах иерархии классов. А модификатор internal служит в основном для сборок.
Для наглядности давайте рассмотрим пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
public byte a; // Открытый член
private byte b; // Закрытый член, указанный явно
byte c; // Закрытый член по умолчанию
public MyClass() { }
public MyClass(byte x, byte y, byte z)
{
a = x;
b = y;
c = z;
}
public void rewrite()
{
Console.WriteLine("Закрытый член b = "+b);
}
}
class Program
{
static void Main()
{
MyClass obj = new MyClass();
obj.a = 10;
// obj.b = 5;
// obj.c = 2; // Данные операции недопустимы
MyClass obj1 = new MyClass(10, 5, 2);
obj1.rewrite();
Console.ReadLine();
}
}
}
Как видите, доступ к членам b и c закрыт, но несмотря на это, свободный доступ к ним организован с помощью конструктора. Из всего сказанного выше можно сделать следующий важный вывод: закрытый член может свободно использоваться другими членами этого же класса, но недоступен для кода за пределами своего класса.
Организация закрытого и открытого доступа
Правильная организация закрытого и открытого доступа — залог успеха в объектно-ориентированном программировании. И хотя для этого не существует твердо установленных правил, ниже перечислен ряд общих принципов, которые могут служить в качестве руководства к действию:
Члены, используемые только в классе, должны быть закрытыми
Данные экземпляра, не выходящие за определенные пределы значений, должны быть закрытыми, а при организации доступа к ним с помощью открытых методов следует выполнять проверку диапазона представления чисел
Если изменение члена приводит к последствиям, распространяющимся за пределы области действия самого члена, т.е. оказывает влияние на другие аспекты объекта, то этот член должен быть закрытым, а доступ к нему — контролируемым
Члены, способные нанести вред объекту, если они используются неправильно, должны быть закрытыми. Доступ к этим членам следует организовать с помощью открытых методов, исключающих неправильное их использование
Методы, получающие и устанавливающие значения закрытых данных, должны быть открытыми
Переменные экземпляра допускается делать открытыми лишь в том случае, если нет никаких оснований для того, чтобы они были закрытыми
Разумеется, существует немало ситуаций, на которые приведенные выше принципы не распространяются, а в особых случаях один или несколько этих принципов могут вообще нарушаться. Но в целом, следуя этим правилам, вы сможете создавать объекты, устойчивые к попыткам неправильного их использования.