Лекция 4 3.3.3. Уровни доступа

advertisement
Лекция 4
3.3.3. Уровни доступа
Уровни доступа задаются для типов и их членов с помощью специальных
модификаторов (public, private, protected и internal). От уровня доступа
зависит, как будут создаваться экземпляры типа и осуществляться доступ к
его элементам.
Модификатор доступа, размещенный перед объявлением некоторого
члена типа, задает его область видимости (scope), то есть определяет, какой
код получит доступ к нему:
 public – доступен из любого места приложения;
 private – доступен только членам этого же типа (в котором определен
данный элемент);
 protected – доступен только членам этого же типа и типов,
производных от него;
 internal – доступен из любого места данной сборки;
 protected internal – совмещает два последних пункта.
Если для члена типа модификатор доступа не задан, то по умолчанию
назначается private.
Модификатор доступа, помещенный перед объявлением типа, управляет
возможностью создания экземпляров этого типа. Создавать экземпляры типа,
объявленного с соответствующим модификатором, может:

public – любой объект приложения;

private – любой объект этого же типа или его контейнера (типа, в
который вложен данный тип);

protected – аналогично private плюс типы, производные от типаконтейнера;

internal – любой объект данной сборки;

protected internal – совмещает два последних пункта.
2
Уровнем доступа по умолчанию для типа является public.
Модификаторы private и protected могут применяться лишь ко вложенным
типам. Вложенный тип, как правило, используется только его типомконтейнером. Поэтому для вложенных типов наиболее подходящим является
уровень private. Тем не менее у вложенного типа может быть указан любой
модификатор доступа, однако его область видимости никогда не будет шире
области видимости типа-контейнера.
3.3.4. Статические члены
Обычно члены типа принадлежат некоторому его экземпляру. Например:
DemoClass Object1 = new DemoClass ();
DemoClass Object2 = new DemoClass ();
Object1.myField = 15; Object2.myField = 43;
Поле myField разных объектов класса DemoClass содержит разные значения.
Однако можно еще создавать члены типа, общие для всех его
экземпляров. Они называются статическими и содержатся в типе в
единственном числе независимо от количества создаваемых объектов. Для
объявления таких членов используется ключевое слово static.
Методы, как и поля, могут быть статическими. Такие методы имеют
доступ только к статическим данным типа.
Статические члены принадлежат самому типу, а не его экземплярам, и
поэтому обращаться к ним можно только по имени самого типа, не создавая
экземпляров. Например:
public class Demo
{
public static int MyField;
}
…………………………………………..
Demo.MyField = 15;
3
Резюме
 Существуют пять модификаторов, определяющих различные уровни
доступа: public, private, protected, internal и protected internal.
 Модификаторы доступа управляют областью видимости членов типа.
 Если для члена не указан модификатор, то в классах и структурах С#
для него по умолчанию принимается уровень доступа private.
 Модификаторы доступа к типам управляют возможностью создания
экземпляров типов.
 Если для класса или структуры модификатор доступа не задан, по
умолчанию для них принимается модификатор public.
 Вложенные типы подчиняются аналогичным правилам, однако их
уровень доступа не может быть больше уровня доступа типаконтейнера.
 Статические члены принадлежат типу, а не его экземплярам, поэтому
они доступны без создания экземпляров типа. К общим членам следует
обращаться по имени класса, а не его экземпляра. Общие методы не
имеют доступа к данным экземпляров типа, в котором они объявлены.
3.4. Преобразование типов
Время от времени требуется преобразовывать одни типы данных в другие.
Подобное преобразование можно выполнить неявно (автоматически) или
явно, когда программист запрашивает преобразование типов.
Неявное преобразование типов возможно только в случае, если оно не
ведет к потере данных, например:
int anInteger = 100;
long aLong;
…
aLong = anInteger; // Потери данных не будет
4
Если некоторый тип разрешается неявно преобразовывать в другой, его
всегда можно использовать вместо второго типа, например, при вызове
методов, причем для этого не нужен никакой специальный синтаксис.
Если требуемое преобразование невыполнимо автоматически, то можно
сделать это явно. Такое преобразование называется приведением (cast)
типов. Для явного преобразования в Visual C# предусмотрен специальный
синтаксис, например:
long aLong = 1000;
int anLnteger;
…
anInteger = (int) aLong;
Для явного преобразования ссылочных типов может также использоваться
оператор as:
Button btn1 = new Button ();
object obj1;
Button btn2;
…
obj1 = btn1; // Работает без явного преобразования
btn2 = obj1 as Button; // Преобразование «вниз»
Заметим, что первое присваивание не требует явного преобразования
типа,
поскольку
все
типы
являются
производными
от
object,
а
преобразования «вверх» по дереву наследования не требуется («кнопка и без
преобразований является объектом»). Оператор as обычно применяется для
преобразования «вниз». Он отличается от первого варианта вида (…) тем, что
первый при неудаче вызывает программную ошибку (исключение), а
оператор as в таком случае вернет null. Явное преобразование типа полезно
предварять проверкой с помощью булевого оператора is, например:
if (obj1 is Button) btn2 = obj1 as Button;
Оператор is может применяться к данным любых типов.
Поскольку явное преобразование типов по своей природе небезопасно,
следует применять его лишь при необходимости и предусматривать
обработку последствий некорректного преобразования.
5
3.5. Встроенная функциональность типов данных
У всех типов данных есть встроенная функциональность, включающая, по
крайней мере, следующие четыре метода типа object:
public bool Equals (object obj); // Сравнивает два объекта
public int GetHashCode ();
// Возвращает хеш-код данного объекта
public Type GetType ();
// Возвращает тип объекта
public string ToString ();
// Возвращает строковое представление объекта
Чтобы
размерные данные могли
поддерживать функциональность
объектов, они подвергаются упаковке (boxing) – неявному преобразованию
типов значений в ссылочные типы. При вызове встроенных методов типа
исполняющая среда создает в стеке временную ссылку, позволяя обращаться
с данными размерного типа как со ссылочным типом.
Упаковку можно выполнять и вручную. Для этого достаточно подлежащее
упаковке значение записать в переменную типа object:
int I = 100;
object O = I;
Обратная операция – преобразование упакованной переменной в тип
значения – называется распаковкой (unboxing). Для распаковки переменной
следует явно привести ее к требуемому типу, но так можно поступать только
с объектами, которые ранее были упакованы.
У типов есть также методы, не унаследованные от класса object. Обычно
они реализуют функциональность, специфичную для типа. Таких методов
очень много, поэтому рассмотрим лишь наиболее популярные из них.
Каждый
размерный
тип
поддерживает
статический
позволяющий получить из строки значение данного типа.
int I;
string S;
S = "1234";
…
I = int.Parse(S);
метод
Parse,
6
Тип данных char поддерживает несколько статических методов, удобных,
например, для анализа символов в строках:
public static bool IsDigit (char c);
public static bool IsLetter (char c);
public static bool IsLetterOrDigit (char c);
public static bool IsPunctuation (char c);
public static bool IsLower (char c);
public static bool IsUpper (char c);
Все они проверяют символ (в соответствии со своим именем) и
возвращают булевы значения.
Во многих приложениях требуется возможность манипулирования
строками (например, преобразования строк в удобный формат, извлечения
подстрок и так далее). Класс string поддерживает разнообразные методы для
работы со строками. Кратко рассмотрим наиболее полезные из них.
public string Insert (int startIndex, string value);
Вставляет строку
value в текущий экземпляр с позиции startIndex
(нумеруется с 0).
public string PadLeft (int aNumber, char aChar);
public string PadRight (int aNumber, char aChar);
Дополняет строку заданным символом слева (справа). Есть вариант
методов с одним параметром – в этом случае строка дополняется пробелами.
public string Remove (int startIndex, int count);
Удаляет из строки указанное количество символов, начиная с заданного.
public string Substring (int startIndex, int count);
Возвращает подстроку. При указании одного параметра берется подстрока
до конца текущей строки.
public char [] ToCharArray ();
Преобразует строку в массив символов.
public string ToLower ();
public string ToUpper ();
Преобразуют строку в нижний (верхний) регистр.
7
public string TrimStart ();
public string TrimEnd ();
public string Trim ();
Удаляют пустые символы (пробелы, табуляции) с начала, с конца или с
обеих сторон строки.
public static int Compare (string strA, string strB, bool ignoreCase);
Этот статический метод сравнивает между собой две строки. Если указать
два параметра, то строки сравниваются с учетом регистра.
Резюме
 Преобразование типов осуществляется двумя способами:
 неявно – их исполняющая среда выполняет автоматически в тех
случаях, когда потеря данных исключена;
 явно – такие преобразования специально определяются в коде.
Они несут потенциальную опасность потери данных, поэтому их
нужно применять с осторожностью.
 Для явных преобразований ссылочных типов имеется специальный
оператор as, который не вызывает исключения при неудаче.
 Для проверки принадлежности переменной некоторому типу удобно
применять оператор is.
 Упаковка позволяет обращаться с размерными данными как со
ссылочными типами – объектами. При распаковке выполняется
преобразование упакованных ссылочных типов в типы значений.

У .NET-типов имеется встроенная функциональность, специфичная для
типа. Метод Parse поддерживают все размерные типы, он удобен для
преобразования строк в типы значений. Классы char и string
предоставляют ряд удобных функций для работы со строками.
Download