Lecture10 (Лекции по Технологии программирования. Компонентный подход), страница 7
Описание файла
Файл "Lecture10" внутри архива находится в папке "Лекции по Технологии программирования. Компонентный подход". PDF-файл из архива "Лекции по Технологии программирования. Компонентный подход", который расположен в категории "". Всё это находится в предмете "основы программной инженерии" из 6 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 7 страницы из PDF
Тогда эта инструкция ничего неделает, и значения входящих в нее выраженийне вычисляются.Если проверка утверждений включена, товычисляется значение expression. Если оноравно true, управление переходит дальше,иначе в обоих случаях выбрасываетсяисключение java.lang.AssertionError.Во втором случае еще до выброса исключениявычисляется значение выраженияexpression_s, оно преобразуется в строку изаписывается в качестве сообщения всоздаваемое исключение.В C# имеется возможность использоватьинструкцию goto. Эта инструкция передаетуправления на инструкцию, помеченнуюметкой, которая следует за goto.Как мы уже видели, помимо обычных меток, вgoto могут использоваться метки case вместесо значениями и метка default.
В этих случаяхинструкция goto должна находиться внутриблока switch, в котором имеются эти метки.При выходе с помощью goto из блока try илиблока catch, у которых имеетсясоответствующий блок finally, сначалавыполняется содержимое этого блока finally.Ключевые слова checked и unchecked в C#могут помечать блок, определяя тем самымконтекст вычислений в рамках этого блока (см.раздел о целочисленных типах).Инструкция using может быть использована вC#, чтобы выполнить действия, требующиезахвата каких-либо ресурсов, безнеобходимости заботиться потом об ихосвобождении.Эта инструкция имеет видusing ( expression ) statement илиusing ( declaration ) statementгде declaration — это декларация одной илинескольких переменных.Первый вид этой инструкции сводится ковторому — если тип используемого выраженияT, и имя v нигде не используется, то онэквивалентенusing ( T v = expression ) statementЭта конструкция, в свою очередь, эквивалентнаследующей.{T v = expression;try { statement }finally { disposal }}Здесь disposal представляет вызов методаDispose(), который должен быть у типа T, свозможной предварительной проверкой того,что переменная v не равна null, и приведениемее к типу System.IDisposable, если T являетсяего подтипом.В версии 2.0 в C# введены две инструкцииyield, предназначенные для более удобногопостроения итераторов.Блок, содержащий инструкцию yield,называется итерационным (iterator block) иможет быть телом метода, оператора илиметода доступа к свойству и не должен бытьблоком finally, catch или блоком try, укоторого есть соответствующие catch-блоки.Этот блок порождает последовательностьзначений одного типа.
Сам метод или оператордолжен возвращать объект одного из четырехтипов:System.Collections.IEnumerable,System.Collections.IEnumerator,System.Collections.Generic.IEnumerable<T>,System.Collections.Generic.IEnumerator<T>.В первых двух случаях порождаются объектытипа object, во вторых двух — значения типа T.Для возвращения одного из этойпоследовательности значений используетсяинструкция yield return expression;Выражение в ней должно иметьсоответствующий тип, object или T.Для указания на то, что порождаемаяитерационным блоком последовательностьзначений завершилась, используетсяинструкция yield break;Пример реализации итератора коллекции сиспользованием yield приведен ниже.using System;public class MyArrayList<T>{T[] items = new T[10];int size = 0;public int Count{ get { return size; } }public T this[int i]{get{if(i < 0 || i >= size) throw newIndexOutOfRangeException();else return items[i];}set{if(i < 0 || i > size) throw newIndexOutOfRangeException();else if (i == size){T[] newItems =new T[size + 10];Array.Copy(items, newItems, size++);}items[i] = value;}}}public IEnumerator<T> GetEnumerator(){for(int i = 0; i < size; i++)yield return items[i];}public class A{public static void Main(){MyArrayList<string> l =new MyArrayList<string>();l[0] = "First";l[1] = "Second";l[2] = "Third";}}foreach (string s in l)Console.WriteLine(s);Инструкции обоих языков, предназначенные для синхронизации работы нескольких потоков,рассматриваются в следующей лекции, в разделе, посвященном разработке многопоточныхпрограмм.Пользовательские типыВ обоих рассматриваемых языках имеются ссылочные типы и типы значений.
Объектыссылочных типов имеют собственную идентичность, а значения такой идентичности не имеют.Объекты ссылочных типов можно сравнивать на совпадение или несовпадение при помощиоператоров == и !=. В C# эти операторы могут быть перегружены, поэтому, чтобы сравнитьобъекты на идентичность, лучше привести их сначала к типу object.В обоих языках можно создавать пользовательские ссылочные типы, определяя классы иинтерфейсы. Кроме того, можно использовать массивы значений некоторого типа.
В C# можноопределять пользовательские типы значений, а в Java типами значений являются толькопримитивные.Класс представляет собой ссылочный тип, объекты которого могут иметь сложную структуруи могут быть задействованы в некотором наборе операций. Структура данных объектов классазадается набором полей (fields) этого класса. В каждом объекте каждое поле имеет определенноезначение, могущее быть ссылкой на другой или тот же самый объект.Над объектом класса можно выполнять операции, определенные в этом классе. Термин«операция» будет употребляться для обозначения методов обоих языков, а также операторов,методов доступа к свойствам, индексерам и событиям в C# (см.
ниже). Для каждой операции вклассе определяются ее сигнатура и реализация.Полная сигнатура операции — это ее имя, список типов, значения которых она принимает вкачестве параметров, а также тип ее результата и список типов исключений, которые могут бытьвыброшены из нее. Просто сигнатурой будем называть имя и список типов параметров операции— этот набор обычно используется для однозначного определения операции в рамках класса. Всеоперации одного класса должны различаться своими (неполными) сигнатурами, хотя некоторые изних могут иметь одинаковые имена.
Единственное исключение из этого правила касается толькоC# и будет описано ниже.Реализация операции представляет собой набор инструкций, выполняемых каждый раз, когдаэта операция вызывается. Абстрактный класс может не определять реализации для некоторыхсвоих операций — такие операции называются абстрактными. И абстрактные классы, и ихабстрактные операции помечаются модификатором abstract.Поля и операции могут быть статическими (static), т.е. относиться не к объекту класса, а кклассу в целом. Для получения значения такого поля достаточно указать класс, в котором оноопределено, а не его объект.
Точно так же, для выполнения статической операции не нужноуказывать объект, к которому она применяется.Интерфейс — ссылочный тип, отличающийся от класса тем, что он не определяет структурысвоих объектов (не имеет полей) и не задает реализаций для своих операций. Интерфейс — этоабстрактный тип данных, над которыми можно выполнять заданный набор операций. Какиеконкретно действия выполнятся для данного объекта, зависит от его точного типа (в обоихслучаях это может быть класс, реализующий данный интерфейс, а в C# — еще и структурный тип,тоже реализующий данный интерфейс).Из последней фразы может быть понятно, что и в Java, и в C# объект может относиться сразу кнескольким типам. Один из этих типов, самый узкий, — точный тип объекта, а остальные(более широкие) являются классами-предками этого типа или реализуемыми им интерфейсами.Точным типом объекта не может быть интерфейс или абстрактный класс, потому что для них неопределены точные действия, выполняемые при вызове (некоторых) их операций.Классы и интерфейсы (а также отдельные операции) в обоих языках могут быть шаблонными(generic), т.е.
иметь типовые параметры (соответствующие конструкции введены в Java 5 иC# 2.0). При создании объекта такого класса нужно указывать конкретные значения его типовыхпараметров.Примеры деклараций классов и интерфейсов для обоих языков приведены ниже. В обоихслучаях определяется шаблонный интерфейс очереди, которая хранит объекты типа-параметра, икласс, реализующий очередь на основе ссылочной структуры. Показан также примериспользования такой очереди.using System;public interface Queue <T>{void put (T o);Tget ();int size();}public class LinkedQueue <T>implements Queue <T>{public void put (T o){if(last == null){first = last = new Node <T> (o);}else{last.next = new Node <T> (o);last = last.next;}size++;}public interface IQueue <T>{void Put (T o);TGet ();int Size();}public class LinkedQueue <T>: IQueue <T>{public void Put (T o){if(last == null){first = last = new Node <T> (o);}else{last.next = new Node <T> (o);last = last.next;}size++;}public Tget (){if(first == null) return null;else{T result = first.o;if(last == first) last = null;first = first.next;size--;return result;}}public TGet (){if(first == null) return default(T);else{T result = first.o;if(last == first) last = null;first = first.next;size--;return result;}}public int size(){return size;}public int Size(){return size;}private Node <T> last = null;private Node <T> first = null;private intsize = 0;private Node <T> last = null;private Node <T> first = null;private intsize = 0;private static class Node <E>{internal class Node <E>{ENode<E>Node (E o){this.o = o;}}}public class Program{public static void main(String[] args){Queue<Integer> q =new LinkedQueue<Integer>();}}internal Eo= default(E);internal Node <E> next = null;o= null;next = null;internal Node <E> (E o){this.o = o;}}}public class Program{public static void Main(){Queue<int> q =new LinkedQueue<int>();for(int i = 0; i < 10; i++)q.put(i*i);for(int i = 0; i < 10; i++)q.Put(i*i);while(q.size() != 0)System.out.println("Next element + 1: " +(q.get()+1));while(q.Size() != 0)Console.WriteLine("Next element + 1: " +(q.Get()+1));}}Обе программы выдают на консоль текстNextNextNextNextNextNextNextNextNextNextelementelementelementelementelementelementelementelementelementelement++++++++++1:1:1:1:1:1:1:1:1:1:12510172637506582На основе пользовательского или примитивного типа можно строить массивы элементовданного типа.