Рабочая программа по дисциплине Цели и задачи освоения дисциплины Дисциплина Объектноориентированный анализ и программирование
Скачать 339.98 Kb.
|
public static void main(String args) { System, out .printin (“Привет ! Я —твой компьютер.”); System.out.flush(); Предлагаемый код необходимо сохранить в файл Example.java. Обратите внимание — важно, чтобы файл с исходным кодом имел расширение java и имя, совпадающее с названием главного класса. После выполнения команды javac Example.java из содержащего файл каталога в нем же будет создан файл с байт-кодом Example.class. Запустить только что созданную программу можно с помощью команды «java <имя файла>». В нашем примере выполнение команды java Example (именно так, без расширения) приведет к выводу на экран строки «Привет! Я — твой компьютер.». С аппаратной точки зрения команда «java» создаст в памяти ЭВМ отдельную копию виртуальной машины. После этого байт-код, содержащийся в файле Example.class будет проинтерпретирован. Обратите внимание, что в зависимости от используемой Вами операционной системы могут понадобиться дополнительные действия. Например, команды «javac» и «java» в операционной системе Windows ХР будут работать только после добавления пути к каталогу jdk\bin в переменную окружения Path. Простейшая программа на языке Java Рассмотрим подробнее представленный выше пример. Файл Example Java содержит описание одного единственного класса с публичным модификатором доступа (речь о модификаторах доступа пойдет ниже). Класс Example содержит единственный метод — main. В качестве аргументов метод принимает массив строк-параметров (String[] args). Кроме того, метод main является не только публичным, но и статическим (статические методы также будут рассмотрены ниже). Тело метода состоит из двух команд. Обе команды обращаются к встроенному классу System. Данный класс позволяет использовать некоторые системные функции, содержит ряд статических методов и доступен для всех программ по умолчанию. Первая команда осуществляет вывод строки-параметра на экран (через обращение к потомку out, являющемуся членом класса System). Вторая команда предназначена для сброса буфера и вывода еще не выведенного содержимого на экран. В зависимости от используемой аппаратной и программной платформы данная команда может являться не обязательной. Обратите внимание на название и способ объявления метода. Дело в том, что main является своеобразной «точкой входа» для виртуальной машины. Любая java-программа должна иметь главный класс, содержащий именно такой метод. Таким образом, работа любой программы начинается с выполнения команд, расположенных в данном методе. Наиболее важные особенности языка программирования Java В данном разделе будут освещены наиболее интересные и важные с практической точки зрения особенности языка программирования Java. Для знакомства с базовым синтаксисом языка, если это требуется, рекомендуется обратиться к специализированной литературе. Встроенные типы данных и механизм автоупаковки Как и любой язык программирования Java обладает набором встроенных типов данных: целых, вещественных, логических и символьных. К целочисленным типам данных относятся byte (диапазон допустимых значений от -128 до 127), short (диапазон допустимых значений от -32768 до 32767), int (диапазон допустимых значений от -2147483648 до 2147483647) и long (диапазон допустимых значений от -9223372036854775808 до 9223372036854775807). Обратите внимание на то, что Java не позволяет работать с беззнаковыми целыми числами. К вещественным типам данных относятся float (приблизительный диапазон допустимых значений от -1.4е-045 до 3.4е+038) и double (приблизительный диапазон допустимых значений от -4.9е-324 до 1.8е+308). Данные типы полностью соответствуют стандартным числам с одинарной и двойной точностью, описанным в стандарте IEEE-754. Использование double рекомендуется в тех случаях, когда требуется повышенная точность (способен обеспечить точность до 15-16 значащих цифр; ширина 64 бита). Применение вещественных чисел типа float позволяет сэкономить память (ширина 32 бита). Для работы с логическими выражениями полезным может оказаться тип boolean. Переменные данного типа способны принимать одно из двух значений: true или false. Для работы с символьными данными используются типы данных char и Siring (формально, String — это не тип данных, а класс; однако на практике использовать экземпляры данного класса приходится настолько часто, что речь о нем пойдет в этом разделе). Важно помнить, что в отличие от подавляющего большинства языков программирования тин char в Java двухбайтовый. Именно такая размерность необходима для представления символов в Юникоде (эта кодировка используется в java-npoipaMMax по умолчанию как наиболее универсальная). Интересным является то, что экземпляры класса String являются неизменяемыми. Это значит, что, например, приписывание к существующей строке одного символа приведет к созданию нового объекта. Данная особенность не может не сказываться на быстродействии. Если возникает необходимость в частом изменении строковых объектов, возможно, лучше воспользоваться классом StringBuilder. В версии 1.5 для стандартного средства вывода данных PrintWriter был добавлен метод prinlf, с помощью которого можно весьма просто осуществлять форматированный вывод. В основе предлагаемого подхода лежит механизм, использующий строку спецификации (схожая идея применяется в ряде других языков программирования, таких как C++ и С#). Начиная с версии 1.7 для ввода-вывода предлагается использовать средства пакета то. Крайне полезной особенностью Java является встроенная длинная арифметика. Работа с длинными целыми числами осуществляется с помощью класса Biginteger. С вещественными числами большой разрядности позволяет работать класс BigDccimal. Данные классы позволяют выполнять целый ряд операций с числами: сложение, вычитание, умножение, деление, деление с остатком, побитовый сдвиг, проверка простоты, поиск наибольшего общего делителя и так далее. Одной из наиболее интересных особенностей Java является механизм автоупаковки. Известно, что Java — полностью объектно-ориентированный язык. Однако, можно заметить, что в в стандарте языка присутствуют характерные для многих языков тины данных: byte, short, int, long, float, double, boolean и char. Каким же образом язык может быть с одной стороны полностью объектным, а с другой поддерживать работу с базовыми типами? Секрет в том, что Java имеет также классы, эквивалентные каждому из этих типов: Byte, Short, Int, Long, Float, Double. Boolean и Char. Там, где это возможно, интерпретатор оперирует примитивами. Если же работа с ними идет в разрез с объектно-ориентированной парадигмой, неявно выполняется преобразование примитивов в соответствующие классы. Этот механизм получил название «автоупаковка». С его помощью достигается баланс между производительностью и парадигмальной целостностью. Кроме того, предлагаемые классы-заменители позволяют выполнять множество полезных операций: преобразование числа в строку и обратно, перевод числа из одной системы счисления в другую и так далее. Массивы и коллекции Java позволяет взаимодействовать с именованными группами отдельных объектов. Объявление массива выполняется согласно следующему шаблону. <тип данных>[] <имя массива> = new <тип данных>[<размерность>]; Объявление многомерных массивов выполняется аналогичным образом. Например, трехмерный массив описывается следующим образом. <тип данных>[][][] <имя массива> = new <тип данных>[<размерность 1>][<размерность 2>][<размерноеть 3>]; Все массивы индексируются с нуля. Массив заранее известных величин может быть создан с помощью следующего шаблона. <тип данных> [] <имя массива> = {<список значений:»}; При этом значения перечисляются через запятую. Важно помнить, что при создании массива классов сами элементы не будет созданы (то есть все элементы будут тождественны null), а будет выделена память только под массив в целом. Для инициализации придется вызвать консгруктор для каждого элемента. Java также поддерживает работу с коллекциями элементов. Среди наиболее интересных реализаций коллекций стоить отметить Vector (позволяет работать с массивами переменной длины), Array List (также работает с динамическими массивами, отличается от Vector скоростью выполнения некоторых операций), LinkedList (позволяет работать с группой элементов как со связным списком), HashSet (создает коллекцию, которая использует для хранения элементов хэш-таблицу), TreeSet (использует для хранения элементов древовидную структуру), PriorityQucue (создает очередь с приоритетами на базе компаратора), ArrayDcque (позволяет работать с двунаправленной очередью). Коллекция может включать как элементы примитивных типов (точнее, их объектных оберток), так и элементы сложных типов. Например, вектор элементов пользовательского типа (класса) Point может быть объявлен с помощью следующей команды. Vector points new Vector (); Для перебора элементов коллекции может быть использована альтернативная запись цикла for, обычно называемая for-each. Она имеет следующую форму. £ог(<тип элементов> <переменная>: <коллекция>) { } Указанная переменная последовательно примет значение всех элементов коллекции, состоящей из элементов данного типа. Данная форма цикла может быть применена для любого тина коллекций (в том числе и пользовательского), реализующего интерфейс Iterable. Область видимост и элемент ов и пакетная организация иерархической структуры Для более гибкой организации каталогов исходных кодов в Java применяется знакомый из предыдущих материалов пакетный подход. Пакет, как правило, включает в себя группу классов, предназначенных для решения одной задачи (например, обработка текста, отформатированного согласно шаблону) или схожих по своему назначению (например, библиотека алгоритмов матричной алгебры). Для указания того, что класс принадлежит определенному пакету, необходимо предварить описание строкой «package <имя пакета>;». Таким образом, данная строка должна быть первой строкой файла. Кроме того, с точки зрения операционной системы исходный файл должен лежать в соответствующем пакету каталоге. На название пакета распространяются те же ограничения, что и названия классов, методов и переменных. Если пакет не указан явным образом, то класс будет помещен в пакет по умолчанию (default). Обычно, в названии пакетов используются только символы нижнего регистра. Пусть класс Figure необходимо поместить в пакет geometry. Тогда инструкция указания пакета будет иметь такой вид. package geometry; Классы, расположенные в разных пакетах изначально недоступны друг для друга. Для того, чтобы оперировать экземплярами класса из другого пакета, необходимо явным образом указать интерпретатору месторасположение такого класса. Сделать это можно с помощью инструкции «import сполный путь к классу в иерархии пакетов>;». Например, если класс Figure расположен в пакете geometry, который в свою очередь расположен в пакете example, то инструкция импорта будет иметь следующий вид. import example.geometry.Figure; С помощью символа «*» можно импортировать все классы, содержащиеся в пакете. Так, чтобы интерпретатор мог работать со всеми классами из пакета example, необходимо добавить такую инструкцию. import example.*; Обратите внимание, что при этом классы из пакета geometry не будут импортированы. В случае, когда требуется импортировать несколько классов, можно указать несколько инструкций импорта друг за другом. Инструкции импорта должны идти сразу же за указанием принадлежности к пакету. Таким образом, формат файла с исходным кодом на языке программирования Java можно описать следующим шаблоном. синструкция принадлежности к пакету> <инструкции импорта> <код> Полезным средством является статический импорт, который позволяет обращаться к статическим членам без явного указания класса-владельца. Рассмотрим данную функцию на примере. Пусть метод getSquareO класса Circle выглядит следующим образом. public double getCirclef) { return 3.14 * Math.pow(this.radius, 2); При вычислении площади круга происходит обращение к методу pow класса Math, который возвращает результат возведения первого аргумента в степень, равную второму аргументу. Класс Math содержится в пакете java.lang, поэтому не нуждается в импорте. Статический импорт позволяет обращаться к методу pow без указания класса-владельца. Для этого необходимо использовать инструкцию import с ключевым словом static. import static java._ang.Math.pow; Теперь метод gctSquare() может быть записан следующим образом. public double getCircle() { return 3.14 * pow(this.radius, 2); Инструкция статического импорта также допускает использование символа «*» для добавления всех статических членов. Несмотря на все преимущества статического импорта важно не злоупотреблять им, так как любая операция импорта (не только статического) замедляет процесс интерпретации (JVM приходится обращаться к большему числу классов). Кроме того важно помнить о проблеме конфликтов в пространстве имен. Добавление совершенно ненужного класса с помощью символа «*» может привести к сокрытию необходимого в работе члена класса. После рассмотрения реализации механизма пакетов в Java можно перейти к классификации областей видимости. В Java каждый член класса может иметь один из грех спецификторов видимости. Элемент класса, объявленный с ключевым словом «public» будет виден для всех остальных классов. Элемент класса, объявленный с ключевым словом «private» будет виден только внутри данного класса. Элемент класса, объявленный с ключевым словом «protected» будет виден внутри данного класса и внутри всех потомков. Наконец, элемент класса, объявленный без какого-либо модификатора будет виден только в пределах пакета. Например. class Circle { private double radius; public double getRadius() { return this.radius; public void setRadius(double radius) { this.radius = radius; В данном примере поле radius является скрытым для всех других классов. Для доступа к нему необходимо использовать публичные методы gclRadiusO и sciRadius(). Спецификаторы видимости позволяют гибко манипулировать доступом к данным и методам. Нс стоит пренебрегать ими. Общее правило таково — если посторонним не нужно знать ничего о поле или иметь возможность вызвать метод, то лучше скрыть такой член класса от доступа (вспомните об одном из принципов объектно-ориентированного профаммирования — инкапсуляции). Статические члены класса Статическим членом в Java называется такой член, доступ к которому возможен без создания экземпляра класса. Зачем нужны такие члены? В некоторых случаях бывает удобно манипулировать сущностью без указания конкретного экземпляра. Пример подобной ситуации — необходимость создания класса-логгера, который бы вел журнал с описанием всех изменений, произошедших в системе. Здесь целесообразно использовать в качестве логгера класс со статическими методами для записи в журнал. Такое решение позволить упростить получение доступа к журналу (нс потребуется ссылка на конкретный экземпляр класса). Для того чтобы объявить статический метод, необходимо указать перед ним ключевое слово sialic. Вспомните описание метода main класса Example. Подобным образом и реализуется точка входа в систему. Статический характер main обеспечивает возможность выполнение данного метода в самом начале работы программы, когда не создано еще ни одного класса. Для создания статического поля точно также используется ключевое слово static. Рассмотрим пример. Пусть имеются два класса: TestWrilcr и SlalicTeslWrilcr. public class Testwriter { |