В.В. Кулямин - Технологии программирования. Компонентный подход (1134162), страница 49
Текст из файла (страница 49)
Структура данных объектов классазадается набором полей (fields) этого класса. В каждом объекте каждое поле имеет определенноезначение, могущее быть ссылкой на другой или тот же самый объект.Над объектом класса можно выполнять операции, определенные в этом классе. Термин«операция» будет употребляться для обозначения методов обоих языков, а также операторов,методов доступа к свойствам, индексерам и событиям в C# (см.
ниже). Для каждой операции вклассе определяются ее сигнатура и реализация.Полная сигнатура операции — это ее имя, список типов, значения которых она принимает вкачестве параметров, а также тип ее результата и список типов исключений, которые могут бытьвыброшены из нее. Просто сигнатурой будем называть имя и список типов параметров операции— этот набор обычно используется для однозначного определения операции в рамках класса.
Всеоперации одного класса должны различаться своими (неполными) сигнатурами, хотя некоторые изних могут иметь одинаковые имена. Единственное исключение из этого правила касается толькоC# и будет описано ниже.Реализация операции представляет собой набор инструкций, выполняемых каждый раз, когдаэта операция вызывается. Абстрактный класс может не определять реализации для некоторых163своих операций — такие операции называются абстрактными. И абстрактные классы, и ихабстрактные операции помечаются модификатором 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 Tget (){if(first == null) return null;else{T result = first.o;if(last == first) last = null;first = first.next;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 default(T);else{T result = first.o;if(last == first) last = null;first = first.next;164size--;return result;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>}}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;Node (E o){this.o = o;}}}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На основе пользовательского или примитивного типа можно строить массивы элементовданного типа.
Тип массива является ссылочным и определяется на основе типа элементов массива.Количество элементов массива в обоих языках — это свойство конкретного объекта-массива,которое задается при его построении и далее остается неизменным. В обоих языках можно строитьмассивы массивов и пр.В Java можно строить только одномерныемассивы из объектов, которые, однако, самиВ C# есть возможность строить многомерныемассивы в дополнение к массивам массивов.165могут быть массивами.int[] array = new int[3];String[] array1 =new String[]{"First","Second"};int[][] arrayOfArrays = new int[][]{{1, 2, 3}, {4, 5}, {6}};Количество элементов в массиве доступно какзначение поля length, имеющегося в каждомтипе массивов.int[] array = new int[3];string[] array1 =new string[]{"First","Second"};int[][] arrayOfArrays = new int[][]{{1, 2, 3}, {4, 5}, {6}};int[,] twoDimensionalArray =new int[,] {{1, 2}, {3, 4}};Любой тип массива наследует системному типуSystem.Array, и любой объект-массив имеетвсе свойства и методы этого типа.Общее количество элементов в массиве (во всехразмерностях) доступно как значение,возвращаемое свойством Length.
Количествоизмерений в массиве — значение свойства Rank.В обоих языках есть возможность декларировать перечислимые типы (enums), объектыкоторых представляются именованными константами. Однако реализована эта возможность поразному.В Java перечислимые типы (введены в Java 5)являются ссылочными, частным случаемклассов. По сути, набор константперечислимого типа — это набор статически(т.е. во время компиляции, а не в динамике, вовремя работы программы) определенныхобъектов этого типа.Невозможно построить новый объектперечислимого типа — декларированныеконстанты ограничивают множество еговозможных значений.
Любой его объектсовпадает с одним из объектов-констант,поэтому их можно сравнивать при помощиоператора ==.Пример декларации перечислимого типаприведен ниже.В C# перечислимые типы являются типамизначений, определяемыми на основе некоторогоцелочисленного типа (называемого базовым; поумолчанию это int). Каждая константапредставляет собой некоторое значениебазового типа. Однако можно искусственнопостроить другие значения перечислимого типаиз значений его базового типа.Пример декларации перечислимого типаприведен ниже.public enum Coin{PENNY ( 1),NICKEY ( 5),DIME(10),QUARTER(25);public enum Coin : uint{PENNY= 1,NICKEY = 5,DIME= 10,QUARTER = 25}Coin(int value){ this.value = value; }public int value(){ return value; }private int value;}Как видно из примеров, перечисления в Javaустроены несколько сложнее, чем в C#.Возможны декларации методов перечислимого166типа и их отдельная реализация для каждой изконстант.public enum Operation{ADD {public int eval(int a, int b){ return a + b; }},SUBTRACT {public int eval(int a, int b){ return a - b; }},MULTIPLY {public int eval(int a, int b){ return a * b; }},DIVIDE {public int eval(int a, int b){ return a / b; }};public abstract int eval(int a, int b);}В C# имеется возможность декларироватьпользовательские типы значений, помимоперечислимых.
Такие типы называютсяструктурами.Структуры описываются во многом похоже наклассы, они так же могут реализовыватьинтерфейсы и наследовать классам, но имеютряд отличий при использовании,инициализации переменных структурных типови возможности описания различных членов. Всеэти особенности связаны с тем, что структуры— типы значений. Две переменныхструктурного типа не могут иметь однозначение — только равные.
Значениеструктурного типа содержит все значенияполей. При инициализации полей структурыиспользуются значения по умолчанию для ихтипов (0 для числовых, false для логическоготипа, null для ссылочных типов и построенноетак же значение по умолчанию дляструктурных).Пример декларации структуры приведен ниже.public struct Point2D{private double x;private double y;public Point2D(double x, double y){this.x = x;this.y = y;}167public double X() { return x; }public double Y() { return y; }}Все структуры считаются наследующимиссылочному типу object, поэтому возможноприведение значения структуры к этому типу.Наоборот, если известно, что данный объекттипа object представляет собой значениенекоторого структурного типа, он может бытьприведен к этому типу.При переводе значений между структурнымтипом и object производятся ихпреобразования, называющиеся упаковкой(autoboxing) — построение объекта, хранящегозначение структурного типа, — и распаковкой(auto-unboxing) — выделение значения изхранящего его объекта.Эти преобразования строят копиипреобразуемых значений.
Поэтому изменениязначения, хранимого в объекте, никак неотражаются на значениях, полученных ранее изнего распаковкой.При присваивании переменной структурноготипа некоторого значения также происходиткопирование этого значения. При присваиваниипеременной ссылочного типа в нее копируетсязначение ссылки, а сам объект, на которыйуказывает эта ссылка, не затрагивается.В Java, помимо явно описанных типов, можноиспользовать анонимные классы (anonymousclasses).Анонимный класс всегда реализует какой-тоинтерфейс или наследует некоторому классу.Когда объект анонимного класса создается вкаком-то месте кода, все описание элементовсоответствующего класса помещается в том жеместе.