
5d272597cde4795f6660f7ba2149dc90.ppt
- Количество слайдов: 130
Программирование на языке Java Что такое Java. История создания
Что такое Java? Java широко известен как новейший объектноориентированный язык, легкий в изучении и позволяющий создавать программы, которые могут исполняться на любой платформе без каких-либо доработок (кроссплатформенность) Java ориентирован на Internet, и самое распространенное его применение небольшие программы, апплеты, которые запускаются в браузере и являются частью HTML-страниц
История создания Java Основные задачи, поставленные перед Sun в 1990 году: n все строится исключительно в соответствии с интересами потребителя n небольшая команда должна спроектировать небольшую аппаратно-программную платформу n платформу нужно воплотить в устройстве, предназначенном для персонального пользования, удобном и простом в обращении
История создания Java n n 1 февраля 1991 года Патрик Нотон, Джеймс Гослинг и Майк Шеридан (Mike Sheridan) вплотную приступили к реализации проекта, который получил название Green. (разработка небольшого устройства с жидкокристаллическим сенсорным экраном, которое будет взаимодействовать с пользователем с помощью анимации, показывая, чем можно управлять и как ) Чтобы создать такой прибор, была необходима разработка специализированной графической системой и программного обеспечения.
История создания Java n n Сначала попытались модифицировать С++, чтобы создать язык для написания программ, минимально ориентированных на конкретные платформы. Однако основное достоинство С++ - скорость программ, но не их надежность. Для реализации кроссплатформенности был создан язык Oa. K (дуб), который в последствии был модифицирован и назван Java.
История создания Java n n n Объектно-ориентированный язык Oa. K обещал стать достаточно мощным инструментом для написания программ, которые могут работать в сетевом окружении. Его объекты, свободно распространяемые по сети, работали бы на любом устройстве, начиная с персонального компьютера и заканчивая обычными бытовыми тостерами. Как язык, ориентированный на распределенную архитектуру, Oa. K имел механизмы безопасности, шифрования, процедур аутентификации, причем все эти возможности были встроенные, а значит, незаметные и удобные для пользователя.
Программирование на языке Java Основы объектноориентированного программирования
Методология процедурноориентированного программирования n n n Основой такой методологии разработки программ являлась процедурная, или алгоритмическая, организация структуры программного кода. Исходным в данной методологии было понятие алгоритма. Алгоритм - это способ решения вычислительных и других задач, точно описывающий определенную последовательность действий, которые необходимо выполнить для достижения заданной цели.
Методология процедурноориентированного программирования Использование процедур позволило разбивать большие задачи на подзадачи, что упростило написание больших программ и позволило уменьшить объем программного кода. n Процедура представляет собой законченную последовательность действий или операций, направленных на решение отдельной задачи. n На языке Pascal описание процедуры выглядит следующим образом: Procedure print. Greeting(name: String) Begin Write("Hello, "); Write. Ln(name); End; n
Методология процедурноориентированного программирования n n Одна из основных особенностей процедурного программирования заключается в том, что оно позволило создавать библиотеки подпрограмм (процедур), которые можно было бы использовать повторно в различных проектах или в рамках одного проекта. При процедурном подходе для визуального представления алгоритма выполнения программы применяется так называемая блок-схема. Соответствующая система графических обозначений была зафиксирована в ГОСТ 19. 701 -90.
Методология процедурноориентированного программирования n n n Появление и интенсивное использование условных операторов и оператора безусловного перехода стало предметом острых дискуссий среди специалистов по программированию. Бесконтрольное применение в программе оператора безусловного перехода goto может заметно осложнить понимание кода. Именно с этого времени отсутствие безусловных переходов стали считать хорошим стилем программирования.
Методология процедурноориентированного программирования n n n Дальнейшее увеличение программных систем способствовало формированию новой точки зрения на процесс разработки программ и написания программных кодов, которая получила название методологии структурного программирования. Ее основой является процедурная декомпозиция предметной области решаемой задачи и организация отдельных модулей в виде совокупности процедур. Пик популярности идей структурного программирования приходится на конец 70 -х - начало 80 -х годов.
Методология объектно-ориентированного программирования n n n Как показала практика, традиционные методы процедурного программирования не способны справиться ни с нарастающей сложностью программ и их разработки, ни с необходимостью повышения их надежности. Во второй половине 80 -х годов возникла потребность в новой методологии программирования, которая была бы способна решить проблемы обработки и манипулирования данными. Ею стало объектно-ориентированное программирование (ООП).
Методология объектно-ориентированного программирования n n После составления технического задания начинается этап проектирования, или дизайна, будущей системы. Объектно-ориентированный подход к проектированию основан на представлении предметной области задачи в виде множества моделей для независимой от языка разработки программной системы на основе ее прагматики.
Методология объектно-ориентированного программирования n n Прагматика определяется целью разработки программной системы. В формулировке цели участвуют предметы и понятия реального мира, имеющие отношение к создаваемой системе. При объектно-ориентированном подходе эти предметы и понятия заменяются моделями, т. е. определенными формальными конструкциями. Модель содержит не все признаки и свойства представляемого ею предмета или понятия, а только те, которые существенны для разрабатываемой программной системы.
Методология объектно-ориентированного программирования Объектно-ориентированный подход обладает следующими преимуществами: n n уменьшение сложности программного обеспечения; повышение надежности программного обеспечения; обеспечение возможности модификации отдельных компонентов программного обеспечения без изменения остальных его компонентов; обеспечение возможности повторного использования отдельных компонентов программного обеспечения.
Объект некоторая сущность, обладающая состоянием и поведением Поведение действия объекта вызванные передачей сообщения или изменением состояния Состояние одно из стабильных условий, в которых объект может существовать, охарактеризованное количественно Могу поменять машину на родной болид F 1 Техник может добавить колёс Уникальность признак объекта, отличающий его от другого объекта Водитель = Михаэль Шумахер Год рождения = 1969 Марка = VW Запас топлива = 11, 5 Число колёс = 4
Методология объектно-ориентированного программирования Введение объектов преследует две цели: n понимание прикладной задачи (проблемы); n введение основы для реализации на компьютере. Объект - это мыслимая или реальная сущность, обладающая характерным поведением и отличительными характеристиками и являющаяся важной в предметной области Каждый объект имеет состояние, обладает четко определенным поведением и уникальной идентичностью.
Методология объектно-ориентированного программирования Состояние (state) - совокупный результат поведения объекта: одно из стабильных условий, в которых объект может существовать, охарактеризованных количественно; в любой момент времени состояние объекта включает в себя перечень (обычно статический) свойств объекта и текущие значения (обычно динамические) этих свойств. Набор действий, которые может совершать объект, зависит от параметров объекта, его моделирующего. Например, для объекта "Человек" состояниями являются: n текущее положение человека (стоит, сидит, лежит); n наличие удочки (есть – если существует связь между объектами «Человек» и «Удочка» или нет).
Методология объектно-ориентированного программирования Поведение (behavior) - действия и реакции объекта, выраженные в терминах передачи сообщений и изменения состояния; видимая извне и воспроизводимая активность объекта. Например, возможные действия с некоторым файлом операционной системы ПК: создать; открыть; читать из файла; писать в файл; закрыть; удалить. Результат выполнения действий зависит от состояния объекта на момент совершения действия, т. е. нельзя, например, удалить файл, если он открыт кем-либо (заблокирован). В то же время действия могут менять внутреннее состояние объекта - при открытии или закрытии файла свойство "открыт" принимает значения "да" или "нет", соответственно.
Методология объектно-ориентированного программирования n Уникальность (identity) - свойство объекта; то, что отличает его от других объектов. В машинном представлении под параметром уникальности объекта чаще всего понимается адрес размещения объекта в памяти. Identity (уникальность) объекта состоит в том, что всегда можно определить, указывают две ссылки на один и тот же объект или на разные объекты.
Класс Car String brand Int wheels float fuel set. Brand() set. Wheels() set. Fuel() String get. Brand() Int get. Wheels() float get. Fuel() UML представление Класс шаблон поведения объектов с заданными параметрами определяющими состояние Конструктор выполняется при создании объектов Деструктор выполняется при уничтожении объектов
Методология объектно-ориентированного программирования n n Класс - это шаблон поведения объектов определенного типа с заданными параметрами, определяющими состояние. Все экземпляры одного класса (объекты, порожденные от одного класса) имеют один и тот же набор свойств и общее поведение, то есть одинаково реагируют на одинаковые сообщения.
Методология объектно-ориентированного программирования Класс изображается в виде прямоугольника (в соответствии с Unified Modelling Language), состоящего из трех частей. В верхней части помещается название класса, в средней свойства объектов класса, в нижней - действия, которые можно выполнять с объектами данного класса (методы).
Методология объектно-ориентированного программирования Каждый класс также может иметь специальные методы, которые автоматически вызываются при создании и уничтожении объектов этого класса: n конструктор (constructor) - выполняется при создании объектов; n деструктор (destructor) - выполняется при уничтожении объектов. Обычно конструктор и деструктор имеют специальный синтаксис, который может отличаться от синтаксиса, используемого для написания обычных методов класса.
Инкапсуляция объединение данных и кода в объект скрывающий реализацию подпрограммы и предоставляющий программисту исключительно интерфейсы для взаимодействия с подпрограммой Модульность принцип, согласно которому логически связанные между собой подпрограммы, переменные и т. д. группируются в отдельные файлы (модули) Car … … float get. Fuel() Class Car { public static float fuel; … public get. Fuel() { System. out. println(fuel); } }
Методология объектно-ориентированного программирования Инкапсуляция (encapsulation) - это сокрытие реализации класса и отделение его внутреннего представления от внешнего (интерфейса). При использовании объектно-ориентированного подхода не принято применять прямой доступ к свойствам какого-либо класса из методов других классов. Для доступа к свойствам класса принято задействовать специальные методы этого класса для получения и изменения его свойств.
Наследование классы Car и Driver являются потомками класса Track, а класс Track в свою очередь является предком классов Car и Driver Наследование позволяет создавать классы на основании уже существующего, при этом все свойства и методы родительского класса наследуются потомком. Track Car String brand Int wheels float fuel set. Brand() set. Wheels() set. Fuel() String get. Brand() Int get. Wheels() float get. Fuel() Driver String name Int birthday set. Name() set. Birthday() String get. Name() Int get. Birthday()
Методология объектно-ориентированного программирования Наследование (inheritance) - это отношение между классами, при котором класс использует структуру или поведение другого класса (одиночное наследование), или других (множественное наследование) классов. Наследование вводит иерархию "общее/частное", в которой подкласс наследует от одного или нескольких более общих суперклассов. Подклассы обычно дополняют или переопределяют унаследованную структуру и поведение.
Методология объектно-ориентированного программирования Некоторый класс также может наследовать свойства и поведение сразу нескольких классов. Проектирование системы учета товаров в зоомагазине: Все животные в зоомагазине являются наследниками класса "Животное", а также наследниками класса "Товар". Т. е. все они имеют возраст, нуждаются в пище и воде и в то же время имеют цену и могут быть проданы. Множественное наследование на диаграмме изображается точно так же, как одиночное, но линии наследования соединяют класс-потомок сразу с несколькими суперклассами.
Human Полиморфизм String get. Name() Полиморфизм взаимозаменяемость объектов с одинаковым интерфейсом. … Driver d[] = new Driver[40]; Trainer t[] = new Trainer[40]; … for(int i = 0; i < d. length; i++){ d[i]. get. Name() } for(int i = 0; i < t. length; i++){ t[i]. get. Name() } … Driver Trainer String get. Name() … Human h[] = new Human[80]; h[1] = new Driver(); h[2] = new Trainer(); … for(int i = 0; i < h. length; i++){ h. get. Name(); } …
Перегрузка заключается в возможности одновременного существования в одной области видимости нескольких различных вариантов реализации методов, имеющих одно и то же имя, но различающихся типами параметров, к ним применяемым hello Printer Draw() Draw(x 1, x 2, y 1, y 2) Draw(x 1, x 2, x 3, y 1, y 2, y 3) Draw(0, 0, 10) Draw(0, 5, 15, 0, 10, -2)
Методология объектно-ориентированного программирования Полиморфизм (polymorphism) - положение теории типов, согласно которому имена (например, переменных) могут обозначать объекты разных (но имеющих общего родителя) классов. Следовательно, любой объект, обозначаемый полиморфным именем, может по-своему реагировать на некий общий набор операций. В процедурном программировании тоже существует понятие полиморфизма, которое предполагает возможность создания нескольких процедур или функций с одним и тем же именем, но разным количеством или различными типами передаваемых параметров. Такие одноименные функции называются перегруженными, а само явление - перегрузкой (overloading).
Методология объектно-ориентированного программирования Перегрузка функций существует и в ООП и называется перегрузкой методов. Примером использования перегрузки методов в языке Java может служить класс Print. Writer, который применяется, в частности, для вывода сообщений на консоль. Этот класс имеет множество методов println, которые различаются типами и/или количеством входных параметров. Вот лишь несколько из них: n void println() // переход на новую строку n void println(boolean x) // выводит значение булевской //переменной (true или false) n void println(String x) // выводит строку - значение // текстового параметра.
Методология объектно-ориентированного программирования Реализация классов "Легковой автомобиль" и "Грузовой автомобиль": Отношение обобщения обозначается сплошной линией с треугольной стрелкой на конце. Стрелка указывает на более общий класс (класс-предок или суперкласс), а ее отсутствие - на более специальный класс (класс-потомок или подкласс).
Отношения Агрегация (Aggregation) Home Содержит - дом - житель Child Home() 1 0. . n Child() - трасса Track 0. . n Track() Car Ассоциация (Association) - машина Car() 0. . n University Наследование (Inheritance) Student University() Stydent() Метаклассы (Metaclass) Teacher() Метакласс шаблон класса
Типы отношений между классами Возможны следующие связи между классами в рамках объектной модели: агрегация (Aggregation); n ассоциация (Association); n наследование (Inheritance); n метаклассы (Metaclass). n
Агрегация Отношение между классами типа "содержит" (contain) или "состоит из" называется агрегацией, или включением. Например, если аквариум наполнен водой и в нем плавают рыбки, то можно сказать, что аквариум агрегирует в себе воду и рыбок. n _
Агрегация // определение класса Fish public class Fish { // определения поля home (ссылка на объект Aquarium) private Aquarium home; public Fish() {} } // определение класса Aquarium public class Aquarium { // определения поля inhabitants (массив ссылок на объекты Fish) private Fish inhabitants[]; public Aquarium() { } }
Ассоциация Если объекты одного класса ссылаются на один или более объектов другого класса, но ни в ту, ни в другую сторону отношение между объектами не носит характера "владения", или контейнеризации, такое отношение называют ассоциацией (association). В качестве примера можно рассмотреть программиста и его компьютер. Между этими двумя объектами нет агрегации, но существует четкая взаимосвязь. В данном примере имеет место ассоциация "многие-комногим". _
Метаклассы Шаблон, задающий различные классы, называется метаклассом. Объекты порождаются от классов, а классы - от метакласса. Он, как правило, в системе только один. Но существуют языки программирования, в которых можно создавать и использовать собственные метаклассы, например язык Python. Поскольку метакласс сам является классом, то нет никакого смысла в создании "мета-классов".
Достоинства ООП n Классы предоставляют простые интерфейсы для взаимодействия с данными и методами, что упрощает разработку программ. n Программы могут работать, не различая типа объектов. n Инкапсуляция реализует свойство модульности, что облегчает разработку и обновление программы для команды программистов. n На этапе исполнения один объект может быть заменен другим, что позволяет адаптировать алгоритм для текущей задачи (Полиморфизм и Перегрузка). n Наследование упрощает реализацию схожих классов. n Создание "каркаса" (framework) позволяет абстрагироваться для реализации большой системы. n Сокращается время на разработку, которое может быть отдано другим задачам. n Компоненты многоразового использования содержат значительно меньше ошибок, за счёт не однократных проверок. n Когда компонент используется сразу несколькими программами, улучшения, вносимые в него, повышают качество всех дочерних программ. n Использование стандартных компонентов облегчает понимание программы.
Недостатки ООП n Любой метод может быть переопределен, что усложняет документирование. n В сложных иерархиях классы обычно наследуются с разных уровней, что усложняет понимание кода программы и требует реализации специальных инструментов, вроде навигаторов классов. n Если конкретный класс расширяется, то каждый метод обычно сокращают передачей сообщения базовому классу. Реализация операции, таким образом, рассредоточивается по нескольким классам, и чтобы понять, как она работает, приходится внимательно просматривать весь код. n Инкапсуляцией данных не следует злоупотреблять. Чем больше логики и данных скрыто в недрах класса, тем сложнее его расширять. n Неэффективность распределения памяти. n Неэффективность на этапе выполнения. n Излишняя универсальность. Если классы используются лишь там, где это действительно необходимо, то потеря эффективности из-за повышенного расхода памяти и меньшей производительности незначительна.
Программирование на языке Java Лексика языка
Кодировка Технология Java, как платформа, изначально спроектированная для Глобальной сети Internet, должна быть многоязыковой, а значит, обычный набор символов ASCII (American Standard Code for Information Interchange, Американский стандартный код обмена информацией), включающий в себя лишь латинский алфавит, цифры и простейшие специальные знаки недостаточен. Поэтому для записи текста программы применяется более универсальная кодировка Unicode.
Unicode представляет символы кодом из 2 байт, описывая, таким образом, 65535 символов. Это позволяет поддерживать практически все распространенные языки мира. Первые 128 символов совпадают с набором ASCII. Однако требуется некоторое специальное обозначение, чтобы иметь возможность задавать в программе любой символ Unicode, ведь никакая клавиатура не позволяет вводить более 65 тысяч различных знаков. Эта конструкция представляет символ Unicode, используя только символы ASCII.
Unicode Если в программу нужно вставить знак с кодом 6917, необходимо его представить в 16 -ричном формате (1 B 05) и записать: u 1 B 05. Причем буква u должна быть строчной, а шестнадцатеричные цифры A, B, C, D, E, F можно использовать как заглавные, так и строчные. Так можно закодировать все символы Unicode от u 0000 до u. FFFF. Буквы русского алфавита начинаются с u 0410 по u 044 F (код буквы ё u 0451, Ё: u 0401). В последних версиях JDK в состав демонстрационных приложений входит программа Symbol. Test, позволяющая просматривать весь набор символов Unicode.
Анализ программы Компилятор, анализируя программу, сразу разделяет ее на: n пробелы (white spaces); n комментарии (comments); n основные лексемы (tokens).
Пробелы double a = 1, b = 1, c = 6; double D = b * b - 4 * a * c; if (D >= 0) { double x 1 = (-b + Math. sqrt (D)) / (2 * a); double x 2 = (-b - Math. sqrt (D)) / (2 * a); } можно записать и в таком виде: double a=1, b=1, c=6; double D=b*b-4*a*c; if(D>=0) {double x 1=(-b+Math. sqrt(D))/(2*a); double x 2=(-b-Math. sqrt(D))/(2*a); }
Пробелы Пробелами в Java считаются: n ASCII-символ SP, space, пробел, u 0020, десятичный код 32; n ASCII-символ HT, horizontal tab, символ горизонтальной табуляции, u 0009, десятичный код 9; n ASCII-символ FF, form feed, символ перевода страницы (был введен для работы с принтером), u 000 c, десятичный код 12; n завершение строки.
Комментарии не влияют на результирующий бинарный код и используются только для ввода пояснений к программе. В Java комментарии бывают двух видов: n строчные n блочные Строчные комментарии начинаются с ASCIIсимволов // и длятся до конца текущей строки. Как правило, они используются для пояснения именно этой строки, например: int y=1970; // год рождения
Комментарии Блочные комментарии располагаются между ASCII-символами /* и */, могут занимать произвольное количество строк, например: /* Этот цикл не может начинаться с нуля из-за особенностей алгоритма */ for (int i=1; i<10; i++) {. . . }
Комментарии Часто блочные комментарии оформляют следующим образом (каждая строка начинается с *): /* * Описание алгоритма работы * следующего цикла while */ while (x > 0) {. . . } Блочный комментарий не обязательно должен располагаться на нескольких строках, он может даже находиться в середине оператора: float s = 2*Math. PI/*get. Radius()*/; // Закомментировано для отладки
Комментарии // В этом примере текст /*…*/ станет просто // частью строки s String s = "text/*just text*/"; /* Следующая строка станет причиной ошибки при компиляции, так комментарий разбил имя метода get. Radius() */ circle. get/*comment*/Radius(); А такой код допустим: // Комментарий может разделять вызовы функций: cirle. /*comment*/get. Radius(); // Комментарий может заменять пробелы: int/*comment*/x=1;
Комментарии не могут быть вложенными. Символы /*, */, // не имеют никакого особенного значения внутри уже открытых комментариев, как строчных, так и блочных. Таким образом, в примере /* начало комментария /* // /** завершение: */ описан только один блочный комментарий. А в следующем примере компилятор выдаст ошибку. 1. /* 2. comment 3. /* 4. more comments 5. */ 6. finish 7. */
Комментарии Любые комментарии полностью удаляются из программы во время компиляции. Основное их предназначение - сделать программу простой для понимания, в том числе и для других разработчиков, которым придется в ней разбираться по какойлибо причине. Также комментарии зачастую используются для временного исключения частей кода, например: int x = 2; int y = 0; /* if (x > 0) y = y + x*2; else y = -y - x*4; */ y = y*y; // + 2*x;
Комментарии В стандартную поставку JDK, начиная с версии 1. 0, входит специальная утилита javadoc. На вход ей подается исходный код классов, а на выходе получается удобная документация в HTMLформате, которая описывает все классы, все их поля и методы. При этом активно используются гиперссылки, что существенно упрощает изучение программы. Для создания такой документации необходимо использовать комментарии разработчика. Комментарий разработчика записывается так же, как и блочный. Единственное различие в начальной комбинации символов – для документации комментарий необходимо начинать с /**.
Комментарии Первое предложение должно содержать краткое резюме всего комментария. В дальнейшем оно будет использовано как пояснение этой функции в списке всех методов класса. Поскольку в результате создается HTML-документация, то и комментарий необходимо писать по правилам HTML. Допускается применение тегов, таких как и
. Однако теги заголовков с
использовать нельзя. Символ * в начале каждой строки и предшествующие ему пробелы и знаки табуляции игнорируются. Их можно не использовать вообще, но они удобны, когда необходимо форматирование, скажем, в примерах кода.
Комментарии /** * Первое предложение - краткое описание метода. *
* Так оформляется пример кода: *
** А так описывается HTML-список: ** if (condition==true) *{ * x = get. Widht(); * y = x. get. Height(); *} *
- *
- Можно использовать наклонный шрифт курсив, *
- или жирный жирный. *
Комментарии Из этого комментария будет сгенерирован HTML-код, выглядящий примерно так: Первое предложение – краткое описание метода. Так оформляется пример кода: if (condition==true) { x = get. Widht(); y = x. get. Height(); } А так описывается HTML-список: • Можно использовать наклонный шрифт курсив, • или жирный.
Комментарии javadoc поддерживает специальные теги. Они начинаются с символа @. Можно использовать тег @see, чтобы сослаться на другой класс, поле или метод, или даже на другой Internet-сайт. /** * Краткое описание. * * Развернутый комментарий. * * @see java. lang. String * @see java. lang. Math#PI * @see Official * Java site */
Лексемы Виды лексем в Java: n идентификаторы (identifiers); n ключевые слова (key words); n литералы (literals); n разделители (separators); n операторы (operators).
Идентификаторы n n n Идентификаторы – это имена, которые даются различным элементам языка для упрощения доступа к ним. Имена имеют пакеты, классы, интерфейсы, поля, методы, аргументы и локальные переменные. Идентификатор состоит из букв и цифр. Имя не может начинаться с цифры. Java-буквы, используемые в идентификаторах, включают в себя ASCII-символы A-Z (u 0041 -u 005 a), a-z (u 0061u 007 a), а также знаки подчеркивания _ (ASCII underscore, u 005 f) и доллара $ (u 0024). Для идентификаторов не допускаются совпадения с зарезервированными словами (это ключевые слова, булевские литералы true и false и null-литерал null).
Ключевые слова – это зарезервированные слова, состоящие из ASCII-символов и выполняющие различные задачи языка. Abstract, double, int, strictfp, boolean, else, interface, super, break, extends, long, switch, byte, final, native, synchronized, case, finally, new, this, catch, float, package, throw, char, for, private, throws, class, goto, protected, transient, const, if, public, try, continue, implements, return, void, default import, short, volatile, do, instanceof, static, while.
Литералы позволяют задать в программе значения для числовых, символьных и строковых выражений, а также null-литералов. В Java определены следующие виды литералов: n целочисленный (integer); n дробный (floating-point); n булевский (boolean); n символьный (character); n строковый (string); n null-литерал (null-literal).
Целочисленные литералы позволяют задавать целочисленные значения в десятеричном, восьмеричном и шестнадцатеричном виде: n Десятеричный формат традиционен и ничем не отличается от правил, принятых в других языках. n Значения в восьмеричном виде начинаются с нуля, и, конечно, использование цифр 8 и 9 запрещено. n Запись шестнадцатеричных чисел начинается с 0 x или 0 X (цифра 0 и латинская ASCII-буква X в произвольном регистре).
Дробные литералы представляют собой числа с плавающей десятичной точкой. Правила записи таких чисел такие же, как и в большинстве современных языков программирования. Примеры: 3. 14, 2. , . 5, 7 e 10, 3. 1 E-20. Таким образом, дробный литерал состоит из следующих составных частей: n целая часть; n десятичная точка (используется ASCII-символ точка); n дробная часть; n показатель степени (состоит из латинской ASCII-буквы E в произвольном регистре и целого числа с опциональным знаком + или -); n окончание-указатель типа.
Логические литералы имеют два возможных значения – true и false. Эти два зарезервированных слова не являются ключевыми, но также не могут использоваться в качестве идентификатора.
Символьные литералы n n n Символьные литералы описывают один символ из набора Unicode, заключенный в одиночные кавычки, или апострофы (ASCIIсимвол single quote, u 0027). Также допускается специальная запись для описания символа через его код. Символьный литерал должен содержать строго один символ, или специальную последовательность, начинающуюся с .
Символьные литералы Для записи специальных символов (неотображаемых и служебных, таких как ", ', ) используются следующие обозначения: n b u 0008 backspace BS n t u 0009 horizontal tab HT n n u 000 a linefeed LF n f u 000 c form feed FF n r u 000 d carriage return CR n " u 0022 double quote " n ' u 0027 single quote ' n \ u 005 c backslash n восьмеричный код от u 0000 до u 00 ff символа в восьмеричном формате.
Символьные литералы Поддержка ввода символов через восьмеричный код обеспечивается для совместимости с С. Например: '101' // Эквивалентно 'u 0041' Однако таким образом можно задать лишь символы от u 0000 до u 00 ff (т. е. с кодом от 0 до 255), поэтому Unicode-последовательности предпочтительней. Примеры ошибок: n 'u 000 a' // символ конца строки 'n' // правильное обозначение конца строки n 'u 000 d' символ возврата каретки 'r' //правильное обозначение символа возврата каретки.
Строковые литералы состоят из набора символов и записываются в двойных кавычках. Длина может быть нулевой или сколь угодно большой. Любой символ может быть представлен специальной последовательностью, начинающейся с . n "" // литерал нулевой длины n """ //литерал, состоящий из одного символа " n "Простой текст" //литерал длины 13
Null-литерал может принимать всего одно значение: null. Это литерал ссылочного типа, причем эта ссылка никуда не ссылается, объект отсутствует. Разумеется, его можно применять к ссылкам любого объектного типа данных.
Разделители – это специальные символы, которые используются в служебных целях языка. ()[]{}; . ,
Операторы используются в различных операциях – арифметических, логических, битовых, операциях сравнения и присваивания. n = > < ! ~ ? : n == <= >= != && || ++ -n + - * / & | ^ % << >> >>> n += -= *= /= &= |= ^= %= <<= >>>=
Пример программы 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public class Demo { /** Основной метод, с которого начинается выполнение любой Java программы. */ public static void main (String args[]) { System. out. println("Hello, world!"); } }
Операторы присваивания и сравнения x = 1; // присваиваем переменной x значение 1 n x = = 1 // сравниваем значение переменной x с //единицей Оператор сравнения всегда возвращает булевское значение true или false. Оператор присваивания возвращает значение правого операнда. Условие "не равно" записывается как !=. Сочетание какого-либо оператора с оператором присваивания используется при изменении значения переменной. Следующие две строки эквивалентны: n x = x + 1; n x += 1; n
Арифметические операции Наряду с четырьмя обычными арифметическими операциями +, -, *, /, существует оператор получения остатка от деления %, который может быть применен как к целочисленным аргументам, так и к дробным. Остаток может быть положительным, только если делимое было положительным. n 9%5 возвращает 4 n 9%(-5) возвращает 4 n (-9)%5 возвращает -4 n (-9)%(-5) возвращает -4
Арифметические операции Унарные операции инкремент (++) и декремент (--), используемые слева, называются префиксными, справа – постфиксными. В выражении x=++y; сначала вычислится значение ++y, затем вычисленное значение запишется в переменную x.
Логические операторы Первый вариант операторов (&, |) всегда вычисляет оба операнда, второй же – ( &&, || ) не будет продолжать вычисления, если значение выражения уже очевидно. int x=1; (x>0) | calculate(x) // в таком выражении // произойдет вызов // calculate (x>0) || calculate(x) // а в этом – нет Логический оператор отрицания "не" записывается как !. Этот оператор меняет булевское значение на противоположное. int x=1; x>0 // выражение истинно !(x>0) // выражение ложно
Логические операторы Оператор с условием ? : состоит из трех частей – условия и двух выражений. Сначала вычисляется условие (булевское выражение), а на основании результата значение всего оператора определяется первым выражением в случае получения истины и вторым – если условие ложно. Например, так можно вычислить модуль числа x: x>0 ? x : -x
Битовые операции "и", "или", "исключающее или" принимают два аргумента и выполняют логическое действие попарно над соответствующими битами аргументов. Например, вычислим выражение 5&6: 00000101 // число 5 в двоичном виде & 00000110 // число 6 в двоичном виде ------00000100 //результат выполнения операции "и" //попарно над битами в каждой позиции То есть выражение 5&6 равно 4.
Операторы сдвига При сдвиге влево оператором << все биты числа смещаются на указанное количество позиций влево, причем освободившиеся справа позиции заполняются нулями. Рассмотрим примеры применения операторов сдвига для значений типа int, т. е. 32 -битных чисел. Пусть положительным аргументом будет число 20, а отрицательным -21. // Сдвиг влево для положительного числа 20 n 20 << 00 = 0000000000000010100 = 20 n 20 << 01 = 0000000000000101000 = 40 n 20 << 02 = 00000000000001010000 = 80 n. . . n 20 << 28 = 01000000000000000 = 1073741824 n 20 << 29 = 10000000000000000 = -2147483648 n 20 << 30 = 0000000000000000 = 0 n 20 << 31 = 0000000000000000 = 0
Операторы сдвига n n n // Сдвиг влево для отрицательного числа -21 << 00 = 1111111111111101011 = -21 << 01 = 1111111111111010110 = -42 -21 << 02 = 11111111111110101100 = -84. . . -21 << 25 = 11010110000000000000 = -704643072 -21 << 26 = 1010110000000000000 = -1409286144 -21 << 27 = 0101100000000000000 = 1476395008 -21 << 28 = 101100000000000000 = -1342177280 -21 << 29 = 011000000000000000 = 1610612736 -21 << 30 = 11000000000000000 = -1073741824 -21 << 31 = 10000000000000000 = -2147483648
Операторы сдвига При сдвиге вправо все биты аргумента смещаются на указанное количество позиций, соответственно, вправо. Однако встает вопрос – каким значением заполнять освобождающиеся позиции слева, в том числе и отвечающую за знак. Есть два варианта: n Оператор >> использует для заполнения этих позиций значение знакового бита, то есть результат всегда имеет тот же знак, что и начальное значение. n Второй оператор >>> заполняет их нулями, то есть результат всегда положительный.
Операторы сдвига n n n n // Сдвиг вправо для положительного числа 20 // Оператор >> 20 >> 00 = 0000000000000010100 = 20 20 >> 01 = 000000000000001010 = 10 20 >> 02 = 000000000000000101 = 5 20 >> 03 = 00000000000000010 = 2 20 >> 04 = 00000000000000001 = 1 20 >> 05 = 0000000000000000 = 0 // Оператор >>> 20 >>> 00 = 0000000000000010100 = 20 20 >>> 01 = 000000000000001010 = 10 20 >>> 02 = 000000000000000101 = 5 20 >>> 03 = 00000000000000010 = 2 20 >>> 04 = 00000000000000001 = 1 20 >>> 05 = 0000000000000000 = 0
Операторы сдвига n n n n // Сдвиг вправо для отрицательного числа -21 // Оператор >> -21 >> 00 = 1111111111111101011 = -21 >> 01 = 111111111111110101 = -11 -21 >> 02 = 111111111111111010 = -6 -21 >> 03 = 11111111111111101 = -3 -21 >> 04 = 11111111111111110 = -2 -21 >> 05 = 1111111111111111 = -1 // Оператор >>> -21 >>> 00 = 1111111111111101011 = -21 >>> 01 = 0111111111111110101 = 2147483637 -21 >>> 02 = 0011111111111111010 = 1073741818 -21 >>> 03 = 0001111111111111101 = 536870909 -21 >>> 04 = 0000111111111111110 = 268435454 -21 >>> 05 = 0000011111111111111 = 134217727
Программирование на языке Java Типы данных
Типы данных Java является строго типизированным языком. Это означает, что любая переменная и любое выражение имеют известный тип еще на момент компиляции. Такое строгое правило позволяет выявлять многие ошибки уже во время компиляции. Компилятор, найдя ошибку, указывает точное место (строку) и причину ее возникновения, а динамические "баги" (от английского bugs) необходимо сначала выявить с помощью тестирования (что может потребовать значительных усилий), а затем найти место в коде, которое их породило.
Примитивные типы данных n целочисленные ¨ ¨ ¨ n дробные ¨ ¨ n byte short int long char (также является целочисленным типом) float double булевский ¨ boolean
Объектные типы данных Это все классы, интерфейсы и массивы. В стандартных библиотеках первых версий Java находилось несколько сот классов и интерфейсов, сейчас их уже тысячи. Кроме стандартных, написаны многие и многие классы и интерфейсы, составляющие любую Java-программу.
Переменные используются в программе для хранения данных. Любая переменная имеет три базовых характеристики: n имя; n тип; n значение. Имя уникально идентифицирует переменную и позволяет обращаться к ней в программе. Тип описывает, какие величины может хранить переменная. Значение – текущая величина, хранящаяся в переменной на данный момент.
Переменные Работа с переменной всегда начинается с ее объявления (declaration). объявление переменных и возможная инициализация при объявлении описываются следующим образом. Сначала указывается тип переменной, затем ее имя и, если необходимо, инициализатор, который может быть константой или выражением, вычисляемым во время компиляции или исполнения программы. В частности, можно пользоваться уже объявленными переменными. Далее можно поставить запятую и объявить новую переменную точно такого же типа. n int a; n int b = 0, c = 3+2; n int d = b+c; n int e = a = 5;
Примитивные и ссылочные типы данных Переменные простого типа хранят непосредственно свои значения и приравнивании двух переменных происходит копирование данного значения. int a=5; // объявляем первую переменную и // инициализируем ее int b=a; // объявляем вторую переменную и // приравниваем ее к первой a=3; // меняем значение первой print(b); // проверяем значение второй
Примитивные и ссылочные типы данных Ссылочные же переменные хранят лишь ссылки на объекты, причем различные переменные могут ссылаться на один и тот же объект. То есть объектные переменные после приравнивания остаются "связанными" друг с другом, изменения одной сказываются на другой. Point p 1 = new Point(3, 5); Point p 2=p 1; p 1. x=7; print(p 2. x);
Целочисленные типы Тип Bytes Диапазон byte 1 -128… 127 short 2 -32. 768… 32. 767 int -2. 147. 483. 648. . 2. 147. 483. 647 4 long 8 -9. 223. 372. 036. 854. 775. 808. . 9. 223. 372. 036. 854. 775. 807 (примерно 1019) char 2 'u 0000'. . 'uffff', или 0. . 65. 535
Целочисленные типы Над целочисленными аргументами можно производить следующие операции: n операции сравнения (возвращают булевское значение) ¨ ¨ n <, <=, >, >= ==, != числовые операции (возвращают числовое значение) унарные операции + и арифметические операции +, -, *, /, % операции инкремента и декремента (в префиксной и постфиксной форме): ++ и -¨ операции битового сдвига <<, >>> ¨ битовые операции ~, &, |, ^ ¨ ¨ ¨ n n n оператор с условием ? : оператор приведения типов оператор конкатенации со строкой +
Целочисленные типы n n n int i=300000; print(i*i); // умножение с точностью 32 бита long m=i; print(m*m); // умножение с точностью 64 бита print(1/(m-i)); // попробуем получить разность значений int и long Результатом такого примера будет: n -194313216 n 900000 Первое умножение производилось с точностью в 32 бита, более старшие биты были отброшены. Второе – с точностью в 64 бита, ответ не исказился.
Целочисленные типы Время в Java измеряется в миллисекундах. Попробуем вычислить, сколько миллисекунд содержится в неделе и в месяце: n print(1000*60*60*24*7); // вычисление для недели n print(1000*60*60*24*30); // вычисление для месяца Получаем: n 604800000 n -1702967296 Очевидно, во втором вычислении произошло переполнение. Достаточно сделать последний аргумент величиной типа long: n print(1000*60*60*24*30 L); // вычисление для месяца Получаем правильный результат: n 2592000000
Целочисленные типы Все числовые операторы возвращают результат типа int или long. Однако существует два исключения. n Первое из них – операторы инкремента и декремента. n Вторым исключением является оператор с условием ? : . Если второй и третий операнды имеют одинаковый тип, то и результат операции будет такого же типа.
Целочисленные типы Оператор + может принимать в качестве аргумента строковые величины. Если одним из аргументов является целое число, то число будет преобразовано в текст и строки объединятся. n int x=1; n print("x="+x); Результатом будет: n x=1 print(1+2+"text"); n print("text"+1+2); Результатом будет: n 3 text n text 12 n
Целочисленные типы char c='A'; n print(c); n print(c+1); n print("c="+c); n print('c'+'='+с); Результатом будет: n A n 66 n c=A n 225 n
Дробные типы – это float и double. Их длина - 4 и 8 байт, соответственно. Оба типа знаковые. float: 4 байта 3. 40282347 e+38 f; 1. 40239846 e-45 f double: 8 байт 1. 79769313486231570 e+308; 4. 94065645841246544 e-324
Дробные типы нельзя задать литерал заведомо больший, чем позволяет соответствующий тип данных, это приведет к ошибке overflow. И нельзя задать литерал, значение которого по модулю слишком мало для данного типа, компилятор сгенерирует ошибку underflow. n float f = 1 e 40 f; // значение слишком велико, overflow n double d = 1 e-350; // значение слишком мало, underflow
Дробные типы Над дробными аргументами можно производить следующие операции: n операции сравнения (возвращают булевское значение) ¨ ¨ n числовые операции (возвращают числовое значение) ¨ ¨ ¨ n n n <, <=, >, >= ==, != унарные операции + и арифметические операции +, -, *, /, % операции инкремента и декремента (в префиксной и постфиксной форме): ++ и -- оператор с условием ? : оператор приведения типов оператор конкатенации со строкой +
Дробные типы n n print(1/2); 0 print(1/2. ); 0. 5 Достаточно одного дробного аргумента, чтобы результат операции также имел дробный тип. n int x=3; n int y=5; n print (x/y); n print((double)x/y); n print(1. 0*x/y);
Булевский тип Над булевскими аргументами можно производить следующие операции: n операции сравнения (возвращают булевское значение) ¨ n ==, != логические операции (возвращают булевское значение) ! ¨ &, |, ^ ¨ &&, || ¨ n n оператор с условием ? : оператор конкатенации со строкой +
Ссылочные типы Выражение ссылочного типа имеет значение либо null, либо ссылку, указывающую на некоторый объект в виртуальной памяти JVM. Объект (object) – это экземпляр некоторого класса, или экземпляр массива.
Объекты и правила работы с ними Объекты всегда создаются с использованием ключевого слова new, причем одно слово new порождает строго один объект (или вовсе ни одного, если происходит ошибка). После ключевого слова указывается имя класса, от которого мы собираемся породить объект. Если конструктор отработал успешно, то выражение new возвращает ссылку на созданный объект. Эту ссылку можно сохранить в переменной, передать в качестве аргумента в какой-либо метод или использовать другим способом.
Объекты и правила работы с ними Point p=new Point(1, 2); // Создали объект, получили на него ссылку n Point p 1=p; // теперь есть 2 ссылки на точку (1, 2) n p=new Point(3, 4); // осталась одна ссылка на точку (1, 2) n p 1=null; Ссылок на объект-точку (1, 2) больше нет, доступ к нему утерян и он вскоре будет уничтожен сборщиком мусора. n
Объекты и правила работы с ними Рассмотрим пример: n "abc"+"def" При выполнении этого выражения будет создано три объекта класса String. Два объекта порождаются строковыми литералами, третий будет представлять результат конкатенации. Операция создания объекта – одна из самых ресурсоемких в Java. Поэтому следует избегать ненужных порождений.
Ссылочные типы Над ссылочными значениями можно производить следующие операции: n обращение к полям и методам объекта n оператор instanceof (возвращает булевское значение) n операции сравнения == и != (возвращают булевское значение) n оператор приведения типов n оператор с условием ? : n оператор конкатенации со строкой +
Класс Object В Java множественное наследование отсутствует. Каждый класс может иметь только одного родителя. Существует класс, на котором цепочка всегда заканчивается, это класс Object. Именно от него наследуются все классы, в объявлении которых явно не указан другой родительский класс. А значит, любой класс напрямую, или через своих родителей, является наследником Object.
get. Class() Этот метод возвращает объект класса Class, который описывает класс, от которого был порожден этот объект. Класс Class будет рассмотрен ниже. У него есть метод get. Name(), возвращающий имя класса: String s = "abc"; Class cl=s. get. Class(); print(cl. get. Name()); Результатом будет строка: java. lang. String
equals() Этот метод имеет один аргумент типа Object и возвращает boolean. equals() служит для сравнения объектов по значению, а не по ссылке. Сравнивается состояние объекта, у которого вызывается этот метод, с передаваемым аргументом. Point p 1=new Point(2, 3); Point p 2=new Point(2, 3); print(p 1. equals(p 2)); Результатом будет true.
hash. Code() Данный метод возвращает значение int. Цель hash. Code() – представить любой объект целым числом. Особенно эффективно это используется в хэштаблицах.
to. String() Этот метод позволяет получить текстовое описание любого объекта. get. Class(). get. Name()+"@"+hash. Code() Метод get. Name() класса Class уже приводился в пример, а хэш-код еще дополнительно обрабатывается специальной функцией для представления в шестнадцатеричном формате. Например: print(new Object()); Результатом будет: java. lang. Object@92 d 342
finalize() Данный метод вызывается при уничтожении объекта автоматическим сборщиком мусора (garbage collector). В классе Object он ничего не делает, однако в классенаследнике позволяет описать все действия, необходимые для корректного удаления объекта, такие как закрытие соединений с БД, сетевых соединений, снятие блокировок на файлы и т. д. В обычном режиме напрямую этот метод вызывать не нужно, он отработает автоматически. Если необходимо, можно обратиться к нему явным образом.
Программирование на языке Java Имена и Пакеты
Имена. Пакеты Имена используются в программе для доступа к объявленным ранее "объектам", "элементам", "конструкциям" языка. В Java имеются имена: n пакеты n классы; n интерфейсы; n элементы ссылочных типов (поля; методы; внутренние классы и интерфейсы; ) n аргументы (методов; конструкторов; обработчиков ошибок; ) n локальные переменные.
Пакеты (packages) в Java – это способ логически группировать классы, что необходимо, поскольку зачастую количество классов в системе составляет несколько тысяч, или даже десятков тысяч. Кроме классов и интерфейсов в пакетах, могут находиться вложенные пакеты. Синонимами этого слова в других языках являются библиотека или модуль.
Простые и составные имена Имена бывают простыми (simple), состоящими из одного идентификатора (они определяются во время объявления) и составными (qualified), состоящими из последовательности идентификаторов, разделенных точкой.
Элементы У пакетов и ссылочных типов (классов, интерфейсов, массивов) есть элементы (members). Доступ к элементам осуществляется с помощью выражения, состоящего из имен, например, пакета и класса, разделенных точкой. Элементами пакета являются содержащиеся в нем классы и интерфейсы, а также вложенные пакеты.
Простые и составные имена Чтобы получить составное имя пакета, необходимо к полному имени пакета, в котором он располагается, добавить точку, а затем его собственное простое имя. Например, составное имя основного пакета языка Java – java. lang (то есть простое имя этого пакета lang, и он находится в объемлющем пакете java). Внутри него есть вложенный пакет, предназначенный для типов технологии reflect. Составное имя – java. lang. reflect.
Простые и составные имена Для ссылочных типов элементами являются поля и методы, а также внутренние типы (классы и интерфейсы). Элементы могут быть объявлены в классе или получены по наследству от родительских классов и интерфейсов. Простое имя элементов дается при инициализации. Например, to. String(), PI, Inner. Class. Составное имя получается путем объединения простого или составного имени типа, или переменной объектного типа с именем элемента. Например, ref. to. String(), java. lang. Math. PI, Outer. Class. Inner. Class.
Имена и идентификаторы Простое имя состоит из одного идентификатора, а составное - из нескольких. Существует возможность обращаться к полям и методам объектного типа не через имя типа или объектной переменной, а через ссылку на объект, полученную в результате выполнения выражения: n country. get. City(). get. Street();
Имена и идентификаторы Идентификаторы используются для названий меток (label). n num: n for (int num = 2; num <= 100; num++) n { int n = (int)Math. sqrt(num)+1; n while (--n != 1) n { if (num%n==0) n { n continue num; n } n System. out. print(num+" "); n }
Область видимости class Point { int x; int get. X() {return x; // простое имя } } class Test { void main() { Point p = new Point(); p. x=3; // составное имя } }
Область видимости Если обращение, например, к полю, идет из части кода, попадающей в область видимости его имени, то можно пользоваться простым именем, если нет – необходимо применять составное.
Пакеты Программа на Java представляет собой набор пакетов (packages). n Каждый пакет может включать вложенные пакеты, то есть они образуют иерархическую систему. n Пакеты могут содержать классы и интерфейсы и таким образом группируют типы. n Каждый пакет имеет свое пространство имен, что позволяет создавать одноименные классы в различных пакетах.