Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 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; просмотров: 210; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.236 (0.007 с.) |