Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Организация закрытого и открытого доступа
Правильная организация закрытого и открытого доступа - залог успеха в объектно-ориентированном программировании. И хотя для этого не существует твердо установленных правил, ниже перечислен ряд общих принципов, которые могут служить в качестве руководства к действию. - Члены, используемые только в классе, должны быть закрытыми. - Данные экземпляра, не выходящие за определенные пределы значений, должны быть закрытыми, а при организации доступа к ним с помощью открытых методов следует выполнять проверку диапазона представления чисел. - Если изменение члена приводит к последствиям, распространяющимся за пределы области действия самого члена, т.е. оказывает влияние на другие аспекты объекта, то этот член должен быть закрытым, а доступ к нему — контролируемым. - Члены, способные нанести вред объекту, если они используются неправильно, должны быть закрытыми. Доступ к этим членам следует организовать с помощью открытых методов, исключающих неправильное их использование. - Методы, получающие и устанавливающие значения закрытых данных, должны быть открытыми. - Переменные экземпляра допускается делать открытыми лишь в том случае, если нет никаких оснований для того, чтобы они были закрытыми. Разумеется, существует немало ситуаций, на которые приведенные выше принципы не распространяются, а в особых случаях один или несколько этих принципов могут вообще нарушаться. Но в целом, следуя этим правилам, вы сможете создавать объекты, устойчивые к попыткам неправильного их использования.
8.1.3 Практический пример организации управления доступом Для чтобы стали понятнее особенности внутреннего механизма управления доступом, обратимся к конкретному примеру. Одним из самых характерных примеров объектно-ориентированного программирования служит класс, реализующий стек - структуру данных, воплощающую магазинный список, действующий по принципу "первым пришел - последним обслужен". Свое название он получил по аналогии со стопкой тарелок, стоящих на столе. Первая тарелка в стопке является в то же время последней использовавшейся тарелкой. Стек служит классическим примером объектно-ориентированного программирования потому, что он сочетает в себе средства хранения информации с методами доступа к ней. Для реализации такого сочетания отлично подходит класс, в котором члены, обеспечивающие хранение информации в стеке, должны быть закрытыми, а методы доступа к ним - открытыми. Благодаря инкапсуляции базовых средств хранения информации соблюдается определенный порядок доступа к отдельным элементам стека из кода, в котором он используется.
Для стека определены две основные операции: поместить данные в стек и извлечь их оттуда. Первая операция помещает значение на вершину стека, а вторая - извлекает значение из вершины стека. Следовательно, операция извлечения является безвозвратной: как только значение извлекается из стека, оно удаляется и уже недоступно в стеке. В рассматриваемом здесь примере создается класс Stack, реализующий функции стека. В качестве базовых средств для хранения данных в стеке служит закрытый массив. А операции размещения и извлечения данных из стека доступны с помощью открытых методов класса Stack. Таким образом, открытые методы действуют по упомянутому выше"принципу "последним пришел - первым обслужен". Как следует из приведенного ниже кода, в классе Stack сохраняются символы, но тот же самый механизм может быть использован и для хранения данных любого другого типа. Листинг 8.2 // Класс для хранения символов в стеке.
using System;
class Stack { // Эти члены класса являются закрытыми. char[] stck; // массив, содержащий стек int tos; // индекс вершины стека
// Построить пустой класс Stack для реализации стека // заданного размера. public Stack(int size) { stck = new char[size]; // распределить память для стека tos = 0; }
// Поместить символы в стек. public void Push(char ch) { if(tos==stck.Length) { Console.WriteLine(" – Стек заполнен."); return; }
stck[tos] = ch; tos++; }
// Извлечь символ из стека. public char Pop() { if(tos==0) { Console.WriteLine(" -- Stack is empty."); return (char) 0; }
tos--; return stck[tos]; }
// Возвратить значение true, если стек заполнен. public bool IsFull() { return tos==stck.Length; }
// Возвратить значение true, если стек пуст. public bool IsEmpty() { return tos==0; }
// Возвратить общую емкость стека. public int Capacity() { return stck.Length; }
// Возвратить количество объектов, находящихся // в данный момент в стеке. public int GetNum() { return tos; } } Рассмотрим класс Stack более подробно. В начале этого класса объявляются две следующие переменные экземпляра. // Эти члены класса являются закрытыми. char[] stck; // массив, содержащий стек int tos; // индекс вершины стека Массив stck предоставляет базовые средства для хранения данных в стеке (в данном случае - символов). Обратите внимание на то, что память для этого массива не распределяется. Это делается в конструкторе класса Stack. А член tos данного класса содержит индекс вершины стека. Оба члена, tos и stck, являются закрытыми, и благодаря этому соблюдается принцип "последним пришел - первым обслужен. Если же разрешить открытый доступ к члену stck, то элементы стека окажутся доступными не по порядку. Кроме того, член tos содержит индекс вершины стека, где находится первый обслуживаемый в стеке элемент, и поэтому манипулирование членом tos в коде, находящемся за пределами класса Stack, следует исключить, чтобы не допустить разрушение самого стека. Но в то же время члены stck и tos доступны пользователю класса Stack косвенным образом с помощью различных отрытых методов, описываемых ниже. Рассмотрим далее конструктор класса Stack. // Построить пустой класс Stack для реализации стека // заданного размера. public Stack(int size) { stck = new char[size]; // распределить память для стека tos = 0; } Этому конструктору передается требуемый размер стека. Он распределяет память для базового массива и устанавливает значение переменной tos в нуль. Следовательно, нулевое значение переменной tos указывает на то, что стек пуст. Открытый метод Push() помещает конкретный элемент в стек, как показано ниже. // Поместить символы в стек. public void Push(char ch) { if (tos==stck.Length) { Console.WriteLine(" - Стек заполнен."); return; }
stck[tos] = ch; tos++; } Элемент, помещаемый в стек, передается данному методу в качестве параметра ch. Перед тем как поместить элемент в стек, выполняется проверка на наличие свободного места в базовом массиве, а именно: не превышает ли значение переменной tos длину массива stck. Если свободное место в массиве stck есть, то элемент сохраняется в нем по индексу, хранящемуся в переменной tos, после чего значение этой переменной инкрементируется. Таким образом, в переменной tos всегда хранится индекс следующего свободного элемента массива stck. Для извлечения элемента из стека вызывается открытый метод Pop(), приведенный ниже. // Извлечь символ из стека. public char Рор() { if(tos==0) { Console.WriteLine(" - Стек пуст."); return (char) 0; } tos--; return stck[tos]; } В этом методе сначала проверяется значение переменной tos. Если оно равно нулю, значит, стек пуст. В противном случае значение переменной tos декрементируется, и затем из стека возвращается элемент по указанному индексу. Несмотря на то что для реализации стека достаточно методов Push() и Pop(), полезными могут оказаться и другие методы. Поэтому в классе Stack определены еще четыре метода: IsFull(), IsEmpty(), Capacity() и GetNum(). Эти методы предоставляют всю необходимую информацию о состоянии стека и приведены ниже. // Возвратить значение true, если стек заполнен. public bool IsFull() { return tos == stck.Length; }
// Возвратить значение true, если стек пуст. public bool IsEmpty() { return tos==0; }
// Возвратить общую емкость стека.
public int Capacity() { return stck.Length; }
// Возвратить количество объектов, находящихся // в данный момент в стеке. public int GetNum() { return tos; } Метод IsFull() возвращает логическое значение true, если стек заполнен, а иначе - логическое значение false. Метод IsEmpty() возвращает логическое значение true, если стек пуст, а иначе - логическое значение false. Для получения общей емкости стека (т.е. общего числа элементов, которые могут в нем храниться) достаточно вызвать метод Capacity(), а для получения количества элементов, хранящихся в настоящий момент в стеке, - метод GetNum(). Польза этих методов состоит в том, что для получения информации, которую они предоставляют, требуется доступ к закрытой переменной tos. Кроме того, они служат наглядными примерами организации безопасного доступа к закрытым членам класса с помощью открытых методов. Конкретное применение класса Stack для реализации стека демонстрируется в приведенной ниже программе. Листинг 8.3 // Продемонстрировать применение класса Stack.
using System;
// Класс для хранения символов в стеке. class Stack { // Эти члены класса являются закрытыми. char[] stck; // массив, содержащий стек int tos; // индекс вершины стека
// Построить пустой класс Stack для реализации стека // заданного размера. public Stack(int size) { stck = new char[size]; // распределить память для стека tos = 0; }
// Поместить символы в стек. public void Push(char ch) { if(tos==stck.Length) { Console.WriteLine(" – Стек заполнен."); return; }
stck[tos] = ch; tos++; }
// Извлечь символ из стека. public char Pop() { if(tos==0) { Console.WriteLine(" -- Stack is empty."); return (char) 0; }
tos--; return stck[tos]; }
// Возвратить значение true, если стек заполнен. public bool IsFull() { return tos==stck.Length; }
// Возвратить значение true, если стек пуст. public bool IsEmpty() { return tos==0; }
// Возвратить общую емкость стека. public int Capacity() { return stck.Length; }
// Возвратить количество объектов, находящихся // в данный момент в стеке. public int GetNum() { return tos; } }
class StackDemo { static void Main() { Stack stk1 = new Stack(10); Stack stk2 = new Stack(10); Stack stk3 = new Stack(10); char ch; int i;
// Поместить ряд символов в стек stk1. Console.WriteLine("Поместить символы A-J в стек stk1."); for(i=0;!stk1.IsFull(); i++) stk1.Push((char) ('A' + i));
if(stk1.IsFull()) Console.WriteLine("Стек stk1 заполнен.");
// Вывести содержимое стека stk1. Console.Write("Содержимое стека stk1: "); while(!stk1.IsEmpty()) { ch = stk1.Pop(); Console.Write(ch); }
Console.WriteLine();
if(stk1.IsEmpty()) Console.WriteLine("Стек stk1 пуст.\n");
// Поместить дополнительные символы в стек stk1.
Console.WriteLine("Вновь поместить символы A-J в стек stk1."); for(i=0;!stk1.IsFull(); i++) stk1.Push((char) ('A' + i));
// А теперь извлечь элементы из стека stk1 и поместить их в стек stk2. // В итоге элементы сохраняются в стеке stk2 в обратном порядке. Console.WriteLine("А теперь извлечь символы из стека stk1\n" + "и поместить их в стек stk2."); while(!stk1.IsEmpty()) { ch = stk1.Pop(); stk2.Push(ch); }
Console.Write("Содержимое стека stk2: "); while(!stk2.IsEmpty()) { ch = stk2.Pop(); Console.Write(ch); }
Console.WriteLine("\n");
// Поместить 5 символов в стек. Console.WriteLine("Поместить 5 символов в стек stk3."); for(i=0; i < 5; i++) stk3.Push((char) ('A' + i));
Console.WriteLine("Емкость стека stk3: " + stk3.Capacity()); Console.WriteLine("Количество объектов в стеке stk3: " + stk3.GetNum()); } } При выполнении этой программы получается следующий результат. Поместить символы A-J в стек stkl. Стек stkl заполнен. Содержимое стека stkl: JIHGFEDCBA Стек stkl пуст.
Вновь поместить символы A-J в стек stkl. А теперь извлечь символы из стека stkl и поместить их в стек stk2. Содержимое стека stk2: ABCDEFGHIJ
Поместить 5 символов в стек stk3. Емкость стека stk3: 10 Количество объектов в стеке stk3: 5
|
||||||||
Последнее изменение этой страницы: 2016-12-30; просмотров: 130; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.207.126.53 (0.078 с.) |