4598

Основы программирования и алгоритмические языки. Конспект лекций

Конспект

Информатика, кибернетика и программирование

Лекция 1. Введение в язык java История возникновения языка Java Язык Java является одним из самых молодых языков программирования. Он моложе таких популярных языков, как Basic, Pascal, С и С++. Поскольку в момент создания Java язык С++ являлся...

Русский

2012-11-23

211.5 KB

14 чел.

Лекция 1. Введение в язык java

  1.  История возникновения языка Java

Язык Java является одним из самых молодых языков программирования. Он моложе таких популярных языков, как Basic, Pascal, С и С++. Поскольку в момент создания Java язык С++ являлся наиболее используемым для создания коммерческого программного обеспечения, разработчики Java приняли его в качестве основы для  своей работы. Вследствие этого синтаксис языков С++ и Java совпадает почти на 90%. Однако, разумеется, эти языки не совсем идентичны (иначе какой был бы смысл в создании нового языка?). Появление Java отражает желание разработчиков создать более совершенный язык, который полнее бы отражал дух времени и соответствовал новым веяниям в мире компьютерной техники.

Первоначально язык Java предназначался для программирования бытовой техники, например холодильников, микроволновых печей, стиральных машин электронных записных книжек и т.п.

Над созданием этого языка трудилась группа под руководством Джеймса Гослинга, организованная в дочерней компании фирмы Sun Microsystems Inc. Разработчики быстро убедились, что существующие языки программирования (в том числе С++) для их цели не годятся, потому что написанные на них программы требуется перекомпилировать для каждого нового процессора. Кроме того, эти языки настолько сложны, что не позволяют быстро писать надежные программы. Поэтому программисты приняли решение создать новый язык программирования – небольшой, надежный и, главное, не зависящий от платформы. Этот язык назвали Oak (от английского слова «дуб»). Однако внедрить язык Oak на прибыльные рынки интерактивного телевидения и мобильных телефонов сразу фирме Sun не удалось.

В 1993 году большое влияние на развитие нового языка оказало массовое распространение Интернета. Специалисты Sun быстро осознали, что открылось обширнейшее поле для применения программного обеспечения, работающего на компьютере любого типа, подключенного к всемирной сети. Впоследствии эта концепция программирования стала известна под лозунгом: «Сеть – это компьютер».

Появление новой области применения ускорило разработку нового языка, о выпуске первой версии которого вместе с соответствующими библиотеками API было объявлено в 1995 году. Язык пришлось переименовать, так как слово «Oak» невозможно было зарегистрировать в качестве торговой марки. По легенде, новой название – Java – обязано своим происхождением многочисленным чашкам кофе, выпитого Джеймсом Гослингом и его коллегами во время работы.

Первым приложением, целиком написанным на Java, стал веб-браузер HotRunner, переименованный позже в HotJava. Новый браузер, в отличие от изделий Netscape и Microsoft, участвовавших в «войне браузеров», был универсальным.

Одновременно Sun начала предоставлять лицензии на использование технологии Java другим производителям компьютеров и операционных систем: IBM, SGI, Novell, Hewlett Packard, Microsoft. Производитель обязан был придерживаться спецификации, а за это он получал право украшать свою продукцию знаменитым логотипом с изображением чашки горячего кофе. Всеобщее соблюдение технологии Java привело к реализации маркетингового лозунга, который прославил Java на весь мир: «Write once, run anywhere» («Написано однажды, работает везде»).

  1.  Отличительные свойства языка Java

Создатели языка Java определяют свое детище так: «Java – это простой, объектно-ориентированный, сетевой, интерпретируемый, надежный, безопасный, независимый от архитектуры, переносимый, высокопроизводительный, многопоточный и динамический язык».

Несмотря на несколько горделиво-заносчивый дух этого определения, каждое из перечисленных прилагательных достаточно точно описывает одно из ключевых свойств языка Java. Рассмотрим их значение подробнее.

Простота. Из языка исключены элементы, которые усложняют код программы (например, заголовочные файлы и препроцессор), а также портят стиль программирования (например, команда безусловного перехода goto).

Объектная ориентированность. Java с самого начала разрабатывался как объектно-ориентированный язык. Это означает, что программист может сам определять новые классы объектов. Пакеты классов для решения стандартных задач поставляются вместе с языком Java, и разработчик может использовать эти классы в своих приложениях.

Поддержка сетевых приложений. Чтобы лозунг «сеть – это компьютер» соответствовал действительности, язык Java должен позволять проектировать приложения, работающие в сети, точно так же, как если бы они предназначались для работы на изолированном компьютере. Это требование создателями Java выполнено: язык поддерживает различные уровни сетевого подключения, а открывать файл на удаленном компьютере средствами Java не труднее, чем манипулировать с набором данных, хранящимся локально.

Интерпретируемость. Исходные коды (тексты программ) Java переводятся компилятором не в машинный код, а в так называемый байт-код. Инструкции в байт-коде выполняет виртуальная машина Java. Так достигается переносимость программы на Java: один и тот же байт-код одинаково работает на любой платформе, где установлена нужная версия виртуальной машины. Интерпретация программы обычно происходит значительно медленнее, чем выполнение машинного кода, но в случае Java благодаря передовым технологиям разница в скорости не слишком велика.

Надежность. Первоначальным назначением языка Java была помощь в написании программ для бытовой техники, поэтому требование надежности программ предъявлялось к нему с самого начала. Java – строго типизированный язык, то есть тип любой переменной и любого выражения должен быть известен на момент компиляции. Java поддерживает механизм исключений, в результате чего код программы становится более удобопонятным, чем на других языках. Преимуществом языка Java является и наличие администратора памяти или «сборщика мусора» (garbage collector), который автоматически объединяет свободные области памяти, удаляет неиспользуемые объекты, предотвращая появление «дыр» в памяти.

Безопасность. Язык Java содержит в себе механизмы обеспечения безопасности, которые защищают от вредоносного кода (вирусов или червей), представляющего опасность для файловой системы. Все механизмы безопасности основаны на предположении, что верить нельзя никому и ничему. В Java не поддерживается работа с указателями: программист не может зайти «за кулисы» и перенаправить указатели на другую область памяти. Компилятор не принимает решений о размещении данных в памяти, а программист не может при объявлении класса указать место класса в памяти. Важное отличие Java от других языков – верификация байт-кода, полученного из сети. Любая программа может навредить, но разработчиками языка Java сделано все для того, чтобы это предотвратить.

Независимость от архитектуры. Программа на языке Java не компилируется прямо в машинный код процессора, а переводится в байт-код. Главным преимуществом такого способа является возможность запуска приложения в разных операционных системах и на разных аппаратных платформах без необходимости перекомпиляции для каждой новой платформы. Поэтому с помощью Java легко удовлетворить требованиям написания приложений, которые будут работать совершенно одинаково под MS Windows, Mac OS, Linux и клонами UNIX.

Переносимость. Архитектурная независимость и переносимость – это не одно и то же, несмотря на то, что они тесно связаны друг с другом. Когда речь идет о независимости от операционной системы, подразумевают, что код программы должен быть одинаковым для любой операционной системы. А когда говорят о ее переносимости, имеют в виду возможность выполнения программы на любой платформе. Порой соображения переносимости накладывают существенные ограничения на возможности языка. Так, спецификация языка Java точно указывает размер в байтах и поведение при арифметических операциях для основных (простых) типов данных. Пределы переносимости определяются стандартом POSIX (Portable Operating System Interface), обязывающим всех производителей POSIX-совместимых систем поддерживать определенный интерфейс взаимодействия приложения с операционной системой.

Производительность. Java – интерпретируемый язык. Несмотря на это, скорость выполнения программ на языке Java может быть выше, чем у обычных программ, потому что многие современные программы большую часть времени ждут действий пользователя или поступления данных из базы либо из сети. Если же для конкретной программы соображения скорости выполнения приоритетны перед соображениями переносимости, ее можно преобразовать не в байт-код, а непосредственно в машинные коды конкретного процессора. Существует инструмент, позволяющий сделать это не для всего исходного кода программы, а для отдельных методов, которые компилируются в машинные коды по мере надобности: так называемый компилятор Just-In-Time (точно вовремя). Разумеется, выигрывая в производительности, вы теряете в переносимости и надежности программы.

Многопоточность. На сегодняшний день создание многопоточных приложений уже стало более чем нормой. Пользователь такого приложения может одновременно, например, скачивать файл из сети и прослушивать музыку. Java поддерживает написание многопоточных программ, включая возможность запретить выполнение одного и того же задания двумя потоками одновременно.

Динамичность. Под динамичностью понимается подгрузка классов в память (в том числе и из сети) по мере надобности во время выполнения программы. Это сокращает объем используемой оперативной памяти. Для каждого программного объекта во время выполнения есть возможность узнать, к какому классу он принадлежит.

  1.  Первая программа

По сложившейся традиции первая программа будет выводить на экран приветствие: «Hello World!». Прежде чем ее написать и скомпилировать, необходимо установить на компьютере среду разработки Java. Вы можете бесплатно скачать набор инструментов JDK для своей операционной системы с сайта: http://java.sun.com. JDK содержит два важнейших инструмента разработчика: компилятор языка Javajavac – и стандартный интерпретатор java. Пользуется популярностью и среда NetBeans (http://www.netbeans.org). Интегрированные среды разработки автоматизируют множество рутинных действий программиста. Если вы предпочитаете в учебных целях выполнять эти действия вручную, то можете писать программный код в любом текстовом редакторе: Блокнот или Wordpad под Windows, vi или emacs под ОС семейства UNIX. Текстовые процессоры (MS Word и т.п.) использовать нельзя, потому что они сохраняют в документе не только текст, но и данные о его форматировании.

Для большинства языков программирования не важно, как называется файл исходного кода, но для компилятора языка Java имя файла существенно. Поэтому в листинге 1.1, в котором приводится наша первая программа, мы указываем имя, под которым нужно сохранить ее исходный код: HelloWorld.java.

Листинг 1.1. Первая программа

/* Текст нужно сохранить в файле HelloWorld.java” */

public class HelloWorld {

public static void main(String[] args) {

System.out.println (“Hello World!”);

} // закрываем метод main()

} // закрываем класс HelloWorld

РЕЗУЛЬТАТ

Hello World!

Как можно видеть, комментарии в языке Java имеют тот же синтаксис, что и в С++. В начале программы следует объявление открытого (public) класса HelloWorld. Класс в языке Java – основополагающая единица. Любые действия, выполняемые программой на Java, выполняются только в рамках какого-либо класса. Тело класса, которое может содержать объявления переменных, констант и методов (а также коды этих методов), заключается между левой и правой фигурными скобками.

Выполнение программы начинается с вызова процедуры main(). В отличие от других языков в Java все подпрограммы, функции и процедуры являются методами какого-либо класса. Ключевое слово public в объявлении метода main() – это спецификатор доступа, определяющий «видимость» метода из других частей программы. Спецификатор public указывает на открытый метод, то есть доступный не только из любой части этой программы, но также и из других программ. Поскольку метод main() должен быть вызван извне класса, его необходимо объявлять как открытый. Противоположное значение имеет ключевое слово private, делающее метод недоступным. Ключевое слово void указывает на то, что метод main() не возвращает никакого значения. Однако он принимает аргументы, список которых указан после имени метода в круглых скобках. Наличие круглых скобок в объявлении метода обязательно, но, если никаких аргументов передавать ему не предполагается, круглые скобки могут быть пустыми. Наш метод main() принимает единственный аргумент – String[] args, представляющий собой массив объектов типа String.

Методу  всегда передаются аргументы командной строки, поэтому соглашение требует указывать в его объявлении именно такой список параметров (String[] args), даже если эти параметры внутри метода никак не используются. Для всех остальных методов разработчик свободен в выборе количества и типов аргументов и возвращаемого значения.

В фигурных скобках заключено тело метода, то есть его программный код:

System.out.println (“Hello World!”);

Эта строка выводит на экран традиционное приветствие, включая непечатаемый символ перевода строки. Непосредственно выводом строки занимается метод println, который содержится в классе System.out. Этот класс предназначен для связи программы с операционной системой, а его элемент out обеспечивает доступ к устройствам ввода/вывода, в том числе и к стандартной консоли. Каждая команда языка Java заканчивается точкой с запятой.

  1.  Соглашение о структуре каталогов

Спецификация языка Java требует, чтобы файлы с исходными кодами имели расширение .java, то есть ваша операционная система должна поддерживать длинные имена файлов. Единицей компиляции в языке Java является файл исходного кода, содержащий определения одного или нескольких классов. Определению класса предшествует ключевое слово class, за которым следует имя класса и его код в фигурных скобках. Регистр символов имеет значение, так как компилятор языка Java различает строчные и прописные буквы.

Как выбирается имя файла, если тот содержит несколько классов? Дело в том, что один из этих классов должен быть открытым (то есть иметь тип public) и именно его имя должно совпадать с именем файла.

Кроме правила именования файлов, прописанного в спецификации языка, существует ряд неписанных правил, описывающих размещение по каталогам файлов, составляющих проект. Этими правилами, созданными на основе многолетнего опыта множества программистов, руководствуются разработчики каждого крупного проекта на языке Java. Главный каталог проекта должен называться так же, как главный класс проекта. Главным считается класс, который содержит статический метод main(), с вызова которого начинается выполнение программы. Для нашей первой программы этим именем каталога является HelloWorld. Если вы работаете в какой-либо интегрированной среде разработки, то файл проекта следует помещать в этот каталог. Также в нем могут находиться файлы типа README.

В каталоге проекта должно быть несколько подкаталогов:

  •  src: каталог, в котором хранятся исходные тексты – файлы с расширением .java;
  •  classes: каталог для хранения откомпилированного исходного кода – файлы байт-кода с расширением .class;
  •  doc: каталог, в котором находится документация по проекту. Обычно она генерируется автоматически из исходного кода с помощью утилиты javadoc;
  •  bak: архивный каталог. Здесь хранятся резервные копии файлов исходного кода.

Лекция № 2. ЧЕМ JAVA ОТЛИЧАЕТСЯ ОТ С++

  1.  Введение

Поскольку синтаксис языков программирования Java и С++ во многом похож, мы рассмотрим только те конструкции языка Java, которые отличаются от соответствующих конструкций С++.

  1.  Типы данных

Встроенные типы данных Java делятся на две категории: простые (primitive) и ссылочные (reference). К ссылочным типам относятся массивы, классы, интерфейсы и перечисления. Простые типы данных делятся на числовые (целые и вещественные) и логические, причем символьный тип относится к числовым.

Такие естественные для программистов на других языках типы данных, как строковый и дата/время, реализованы в Java как ссылочные: классами String и Date.

Для хранения целых чисел в Java предусмотрены четыре типа данных (табл. 2.1). Все они хранят целые числа со знаком. Беззнаковых числовых типов, как в С/С++, в языке Java нет.

Таблица 2.1

Тип

Разрядность

Диапазон значений

byte

8 битов

-128… 127

short

16 битов

-32 768… 32 767

int

32 бита

-2 147 483 648… 2 147 483 647

long

64 бита

-9 223 372 036 854 775 808… 9 223 372 036 854 775 807

К целочисленным типам относится и тип char, предназначенный для представления одного символа. К хранению символов национальных алфавитов разработчики Java отнеслись с особым вниманием, потому что приложения, написанные на Java, должны были работать по всему миру. В отличие от большинства других языков, где символ занимает один байт, размер типа char в Java составляет 2 байта. Такой размер необходим для хранения символа по стандарту Unicode.

Собственно Unicode – это набор символов, который можно закодировать разными способами. Язык Java использует кодировку UTF-8, которая отводит по одному байту для букв западноевропейских алфавитов, по два байта – для восточноевропейских, а для алфавитов экзотических языков – три и более байтов. При этом строки, содержащие только 7-битные символы из первой половины таблицы ASCII, имеют одинаковое представление как в ASCII, так и в UTF-8.

Переменной типа char можно присвоить в качестве значения одиночный символ – как прописной, так и заглавный. Например, переменной ch можно присвоить букву L:

char ch;

ch = ‘L’;

Вывести на консоль значение переменной типа char можно с помощью метода println():

System.out.println(“Значение переменной ch равно ”+ch);

Поскольку тип данных ch относится к целочисленным, нам ним можно выполнять арифметические операции. Следующий пример демонстрирует применение операторов инкремента ++ и декремента --.

Листинг 2.1. Операции инкремента и декремента над переменной символьного типа

/* Текст нужно сохранить в файле с именем

  “CharArithDemo.java” */

public class CharArithDemo {

public static void main(String[] args) {

 char ch;

ch = ‘L’;

System.out.println(“ch равно ”+ch);

ch++;

System.out.println(“значение ch изменилось на ”+ch);

ch = ‘Д’;

ch--;

System.out.println(“значение ch снова изменилось и равно ”+ch);

} // закрываем метод main()

} // закрываем класс CharArithDemo

РЕЗУЛЬТАТ

ch равно L

значение ch изменилось на M

значение ch снова изменилось и равно Г

Необходимо отметить, что символ (‘A’) и строка из одного символа (“A”) – это совершенно разные вещи с точки зрения языка Java. Данные символьного и строкового типа хранятся в памяти по-разному.

Для представления вещественных чисел Java, как и С++, располагает двумя типами данных: float и double. Причем, тип double используется гораздо чаще, чем float. Например, метод sqrt(), определенный в классе Math и вычисляющий квадратный корень своего аргумента, принимает аргумент типа double и возвращает значение этого же типа.

Листинг 2.2. Пример работы с вещественными числами

//Вычисление длины гипотенузы по теореме Пифагора   public class HypotDemo {

public static void main(String[] args) {

 double cathetus1, cathetus2, hypot;

cathetus1 = 3;

cathetus2 = 4;

hypot = Math.sqrt(cathetus1*cathetus1 +

cathetus2*cathetus2);

System.out.println(“Hypot = ” + hypot);

} // закрываем метод main()

} // закрываем класс HypotDemo

РЕЗУЛЬТАТ

 Hypot = 5

  1.  Литералы

Литерал – это постоянное значение, записанное в программе в читаемой форме. Например, число 100 – это литерал, одиночный символ и текстовая строка тоже могут быть литералами и т.д. Литерал отличается от константы и переменной тем, что ему не может быть присвоено значение. Литерал может иметь значение любого простого типа данных. Тип литерала определяется формой его записи. Например, ‘?’ – это литерал символьного типа, а “?” – строкового; 10 – типа int, а 10.0 – типа double.

Для того, чтобы заставить компилятор считать литерал, опознаваемый им как данные одного типа, данными другого типа, служат модификаторы. Символ L (заглавный или строчный) превращает литерал типа int в литерал типа long:

int n1 = 24;

long n2 = 24L;

Вещественные литералы имеют по умолчанию тип данных double. Чтобы его поменять на float, нужно добавить к присваиваемому значению символ F:

float f1 = 12.34F;

Целочисленные литералы распознаются как тип int, но их можно присваивать также переменным других целых типов: short, byte и char – при условии, что значение литерала не выходит за пределы диапазона для соответствующего типа, а переменной типа long – без всяких условий.

Числа в языке Java можно представлять не только в десятичной, но и в восьмеричной или шестнадцатеричной форме записи:

hex = 0xFF // 255 – в десятичной системе

oct = 011 // 9 – в десятичной системе

Если запись числа начинается с нуля, то число понимается как восьмеричное; если в префиксе «0x», то – как шестнадцатеричное.

Переменной типа char можно присваивать в качестве значения не только алфавитно-цифровой символ, но и такой, который нельзя ввести с клавиатуры – например, символы, посылаемые клавишами «Tab» или «Backspace». Для того чтобы использовать такие символы в литералах, служат так называемые Esc-последовательности, то есть символ обратного слэша, за которым следует код вводимого символа (табл. 2.2).

Таблица 2.2

Последовательность

Значение

\’

Апостроф (single quote)

\”

Кавычка (double quote)

\\

Обратный слэш (backslash)

\r

Возврат каретки (carriage return)

\n

Перевод строки (new line)

\f

Прогон страницы (form feed)

\t

Табуляция (horizontal tab)

\b

Забой (backspace)

\ddd

Код символа в восьмеричной записи (ddd )

\uhhhh

Код символа в шестнадцатеричной записи (hhhh)

Следующий пример показывает, как использовать Esc-последовательности для представления специальных символов внутри строки.

Листинг 2.3. Символы форматирования текста

public class StrDemo {

public static void main(String[] args) {

System.out.println(“Первая строка\nВторая

строка”);

System.out.println(“A\tB\tC”);

System.out.println(“D\tE\tF”);

System.out.println(“Это строковый литерал”);

System.out.println(“Строка с \”кавычками\””);

System.out.println(“O\’Key”);

} // закрываем метод main()

} // закрываем класс StrDemo

РЕЗУЛЬТАТ

Первая строка

Вторая строка

A B C

D E F

Это строковый литерал

Строка с ”кавычками”

OKey

Часто строковые литералы используются для указания пути к некоторому файлу. В ОС Windows символом-разделителем пути служит обратный слэш. Его тоже необходимо экранировать с помощью Esc-последовательности. В ОС Unix для разделения пути служит прямой слэш. Интерпретатор Java позволяет использовать этот символ и на платформе Windows. Рекомендуется для единообразия всегда писать пути через прямой слэш. Экранировать этот символ не нужно.

  1.  Область действия переменных

В большинстве языков программирования области действия переменных бывают локальными и глобальными. Хотя в Java тоже можно использовать такое деление, это будет не совсем точно. Области действия переменных в Java определяются в терминах классов и методов. Сейчас мы рассмотрим только области действия в рамках методов. О доступности классов мы будем говорить позже, излагая основы объектно-ориентированного программирования.

Блоком называется группа команд, заключенных между левой и правой фигурными скобками. Переменная, объявленная внутри блока, доступна из программного кода, находящегося в этом блоке и вложенных в него блоках любого уровня вложенности, и недоступна из внешних по отношению к нему блоков.

Листинг 2.4. Блок как область действия переменных

public class ScopeDemo {

public static void main(String[] args) {

int x = 1;

System.out.println(“x = ”+x);

{ int y = 3;

x = y*3;

}

/* если раскомментировать строку «y = 100», то получим ошибку компиляции: переменная y в текущем блоке не объявлена */

 // y = 100;

} // закрываем метод main()

} // закрываем класс ScopeDemo

Очевидно, что в программе на языке Java могут быть две переменные с одинаковыми именами, если их области действия не пересекаются. В других языках возможна ситуация, когда переменные с одинаковыми именами объявлены во внешнем и внутренних блоках, причем на время работы внутреннего блока внешняя переменная для него как бы не существует. В Java такая ситуация является синтаксической ошибкой.

  1.  Логические операторы

Логические операторы применяются к операндам типа boolean. Обозначения этих операторов представлены в табл. 2.3.

Таблица 2.3

Оператор

Назначение

!

Отрицание (NOT)

&

Конъюнкция (AND)

|

Дизъюнкция (OR)

^

Исключающее ИЛИ (XOR)

&&

Сокращенная конъюнкция

||

Сокращенная дизъюнкция

Сокращенные операторы && и ||, называемые также условными, применяются в условиях команд if, while или do для вычисления значения истинности условия. Эти операторы отличаются от своих аналогов & и | порядком выполнения. При выполнении логической операции вычисляется значение обоих операндов, а для оценки истинности условия вычисление второго операнда может оказаться излишним: например, если первый операнд оператора && имеет значение false, то независимо от значения второго операнда результатом операции будет false. Точно так же, если первый операнд оператора || имеет значение true, то независимо от значения второго операнда результатом операции будет true. В обоих случаях в вычислении второго операнда нет никакой необходимости, и условные операторы его не вычисляют, поэтому они и называются сокращенными.

  1.  Побитовые операторы

Побитовые операции выполняются над отдельными битами операндов и часто используются при решении задач системного программирования. Побитовые операции могут выполняться только над операндами целочисленных типов: byte, char, short, int, long. Перед выполнением операции оба операнда преобразуются к одному типу. Результатом операции является число того же типа. К операндам типа boolean, float или double, а также к экземплярам классов такие операции не применимы. Побитовые операторы представлены в табл. 2.4.

Таблица 2.4

Оператор

Назначение

~

Дополнение (NOT)

&

Побитовая конъюнкция (AND)

|

Побитовая дизъюнкция (OR)

^

Побитовое исключающее ИЛИ (XOR)

<<

Сдвиг влево

>>

Сдвиг вправо

>>>

Беззнаковый сдвиг вправо

«Таблица истинности» побитовых логических операторов приведена в табл. 2.5.

Таблица 2.5

x

y

x&y

x | y

x^y

~x

0

0

0

0

0

1

1

0

0

1

1

0

0

1

0

1

1

1

1

1

1

1

0

0

Побитовая конъюнкция часто используется как средство сброса (выключения) отдельных битов. Если в одном из операндов выражения имеется нулевой бит, то у числа, получающегося в результате выполнения операции AND, бит, стоящий в этой же позиции, будет равен нулю:

10101010&11010011 = 10000010

Другим применением побитового AND является проверка того, установлен ли у проверяемого значения определенный бит:

if ((value & 8) !=0)

 System.out.println(“Четвертый бит установлен”);

Число 8 в двоичной системе счисления записывается как 1000 (четвертый справа бит равен 1, а остальные – 0), и условие выполняется только тогда, когда в значении переменной value четвертый справа бит тоже равен единице.

Побитовую дизъюнкцию удобно использовать для противоположной цели: включения битов, поскольку, если у одного из операндов побитового OR в определенной позиции стоит единица, то в числе, являющемся результатом операции, в этой позиции будет единица вне зависимости от значения второго операнда:

10101010 | 11010011 = 11111011

Побитовая операция XOR устанавливает значение бита в 1, когда два сравниваемых бита – разные:

10111001 ^ 01111111 = 11000110

У операции XOR есть очень интересная функция: она обратима. Если вы используете операцию XOR для X и Y, а в результате получается Z, то когда операндами XOR станут Z и Y, результатом будет X! Этим свойством пользуются особенно часто при кодировании сообщений или в простых видах шифровки.

Операция NOT инвертирует свой операнд:

~ 10111001 = 01000110

 Следующие три оператора выполняют побитовый сдвиг своего первого операнда на количество разрядов, заданное вторым операндом. В отличие от логических операторов в операторах сдвига важен порядок операндов.

При сдвиге влево << освободившиеся справа позиции заполняются нулями. Беззнаковый сдвиг вправо >>>, называемый также логическим сдвигом, заполняет нулями позиции, освободившиеся слева. При знаковом сдвиге вправо >> слева распространяется значение старшего, знакового бита: это так называемый арифметический сдвиг.

В результате любой операции сдвига теряется хотя бы один бит, и не существует способа его восстановить.

Лекция № 3. JAVA – ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ЯЗЫК

  1.  Создание классов

Представьте себе, что ваша программа должна обрабатывать данные о различных автомобилях: легковых, грузовых, автобусах и т. п. При классическом способе программирования для каждого типа автомобилей пришлось бы писать отдельные процедуры, которые бы обрабатывали бы данные, специфические именно для этого типа. Кроме того, для обработки классическим способом информация должна быть представлена в виде, не приспособленном для человеческого восприятия.

Объектный подход избавляет от обоих этих неудобств. Чтобы представить данные об автомобиле в объектном виде, нужно указать свойства, отличающие автомобиль от всех остальных предметов. Выберем в качестве основных характеристик количество перевозимых пассажиров, число колес, максимальную скорость и расход горючего.

Опишем класс Vehicle (транспортное средство), содержащий эти атрибуты.

class Vehicle {

 int passengers; // количество пассажиров

 int wheels;  // количество колес

 int maxspeed; // максимальная скорость

 int burnup;  // расход топлива

}

С объектно-ориентированной точки зрения каждый класс является самостоятельным типом данных, а термины «класс» и «тип» взаимозаменяемы. Для создания объекта (экземпляра класса) Vehicle служит команда new:

Vehicle car1 = new Vehicle();

В результате выполнения этой команды будет выделена область в памяти, содержимое которой интерпретируется как новый объект car1, устроенный так, как это было записано в объявлении класса Vehicle, то есть располагающий собственными экземплярами переменных passengers, wheels, maxspeed и burnup. Чтобы сослаться на одну из этих переменных объекта, нужно указать ее имя после имени объекта через точку. Например, так выглядит установка максимальной скорости автомобиля равной 130 км/ч:

car1.maxspeed = 130;

Следующий пример вычисляет, какое расстояние может проехать автомобиль за полчаса при движении с максимальной скоростью. Текст программы нужно сохранить в файле VehicleDemo.java.

Листинг 3.1. Пример использования класса Vehicle

class Vehicle {

int passengers; // количество пассажиров

int wheels;  // количество колес

int maxspeed; // максимальная скорость

int burnup;  // расход топлива

}

class VehicleDemo {

public static void main(String[] args) {

Vehicle car1 = new Vehicle();

car1.passengers = 2;

car1.wheels = 4;

car1.maxspeed = 130;

car1.maxspeed = 10;

double distance = car1.maxspeed*0.5;

System.out.print(“За полчаса car1 может

проехать”);

System.out.println(distance + ”км.”);

car1 = null;

} // закрываем метод main()

} // закрываем класс VehicleDemo

Для того чтобы эту программу можно было запустить, исходный код должен храниться в файле VehicleDemo.java, потому что именно в этом классе VehicleDemo определен открытый (public) статический (static) метод main(), с которого начинается выполнение программы на языке Java. Класс VehicleDemo является поэтому главным классом программы. В ранних версиях JDK главный класс необходимо было объявлять как открытый (public), теперь это делать необязательно.

Компилятор превратит исходный код в два файла: Vehicle.class и  VehicleDemo.class. Чтобы запустить программу, нужно выполнить команду:

Y:\>java VehicleDemo

За полчаса car1 может проехать 65.0 км.

Теоретически можно создавать неограниченное количество экземпляров одного и того же класса, однако, на практике мы всегда ограничены количеством доступной оперативной памяти. Каждый объект типа Vehicle имеет свои собственные значения переменных. В следующем примере создаются два экземпляра класса Vehicle с различными значениями максимальной скорости и вычисляются пути, проходимые этими автомобилями за 1 час 15 минут.

Листинг 3.2. Пример использования нескольких экземпляров класса Vehicle

class Vehicle {

int passengers; // количество пассажиров

int wheels;  // количество колес

int maxspeed; // максимальная скорость

int burnup;  // расход топлива

}

class MoreVehicleDemo {

public static void main(String[] args) {

Vehicle car1 = new Vehicle();

car1.passengers = 2;

car1.wheels = 4;

car1.maxspeed = 130;

car1.maxspeed = 10;

Vehicle bus1 = new Vehicle();

bus1.passengers = 45;

bus1.wheels = 4;

bus1.maxspeed = 100;

bus1.maxspeed = 40;

double interval = 1.25;

double distanceCar = car1.maxspeed* interval;

double distanceBus = bus1.maxspeed* interval;

System.out.print(“За 1.25 часа car1 может

проехать”);

System.out.println(distanceCar + ‘км.’);

System.out.print(“За 1.25 часа bus1 может

проехать”);

System.out.println(distanceBus + ‘км.’);

} // закрываем метод main()

} // закрываем класс VehicleDemo

В результате объявления переменной car1 (или bus1) она еще не получает никакого значения. Объект физически создается в памяти командой new, возвращающей его адрес, который мы присваиваем переменной car1, и только после этого она становится связанной с объектом.

Поскольку в переменной хранится не сам объект, а указатель на него, то в программе может быть несколько переменных, ссылающихся на один и тот же объект. Продемонстрируем это на примере следующей программы.

 Листинг 3.3. Пример использования указателей на объект

class SimpleVehicle { // упрощенный вариант класса

int passengers;

}

class RefTypes {

public static void main(String[] args) {

SimpleVehicle car1, car2; // две ссылки на объект

car1 = new SimpleVehicle();

car1.passengers = 25;

car2 = car1;

System.out.println(“Количество пассажиров car2

равно ” + car2.passengers);

car2.passengers = 50;

System.out.println(“Количество пассажиров car1

равно ” + car1.passengers);

}

}

РЕЗУЛЬТАТ

Количество пассажиров car2 равно 25

Количество пассажиров car1 равно 50

Из примера видно, что переменные-объекты отличаются от переменных простых типов (int, double и т.п.). При присвоении значения одной переменной другой переменной того же простого типа значение в правой части присваивания копируется в переменную, стоящую в его левой части. А в случае переменных-объектов копируется адрес, хранящийся в переменной, стоящей в правой части присваивания, в результате чего обе переменные начинают ссылаться на одно и то же место в памяти. Такой тип данных называется ссылочным (reference) типом.

  1.  Методы класса

Большинство классов содержат не только собственные переменные, но и собственные функции, которые в этом случае называются методами. Рекомендуется планировать набор методов так, чтобы каждый из них решал только одну определенную задачу.

Листинг 3.4. Пример класса Vehicle с методом

class Vehicle {

int passengers;

int wheels;

int maxspeed;

int burnup;

// объявляем метод

double distance(double interval) {

double value = maxspeed*interval;

return value;

}

}

class VehicleMethod {

public static void main(String[] args) {

Vehicle car = new Vehicle();

car.passengers = 2;

car.wheels = 4;

car.maxspeed = 130;

car.maxspeed = 10;

 

Vehicle bus = new Vehicle();

bus.passengers = 45;

bus.wheels = 4;

bus.maxspeed = 100;

bus.maxspeed = 25;

 

 // расчет пути, пройденного за 0.5 часа

 double time = 0.5;

 double distanceCar = car.distance(time);

double distanceBus = bus.distance(time);

System.out.println(“car пройдет за полчаса путь ”

+ distanceCar + ”км.”);

System.out.println(“bus пройдет за полчаса путь ”

      + distanceBus + км.”);

}

}

  1.  Конструкторы

Конструктор – это специальный метод, который вызывается в момент создания объекта. Имя этого метода совпадает с именем класса. Никакого значения он не возвращает и используется только для присвоения начальных значений переменным объекта.

Листинг 3.5. Пример конструктора

class Number {

int x;

Number(int num) { // конструктор

x = num;

}

}

class NumberDemo {

public static void main(String[] args) {

Number t1 = new Number(9);

Number t2 = new Number(27);

System.out.println(t1.x + “ *** ” + t2.x);

}

}

  1.  Массивы

В отличие от многих других языков массивы в языке Java реализованы как объекты. Пример объявления двухмерного массива:

int mytable[][] = new mytable[30][40];

Первым будет элемент mytable[0][0], а последним – элемент mytable[29][39].

Инициализация массива (т.е. присвоение его элементам начальных значений) происходит так же, как и в языке С++.

Лекция № 4. РАБОТА СО СТРОКАМИ

  1.  Строки в Java

В отличие от классических языков программирования в Java строки реализованы не как основной тип данных, а как класс String. Данный класс входит в пакет классов java.land,  то есть не требует импорта для обращения к строкам.

Класс String относится к числу неизменяемых классов (immutable classes). Это классы с методами, которые не изменяют внутреннее состояние объекта, созданного на их основе, а возвращают новый экземпляр класса. Например, метод concat() не присоединяет строку, переданную в аргументе, к уже существующей строке объекта, а просто формирует новый объект – экземпляр класса String, содержащий полную строку. Докажем это на примере.

String str1 = “Красота спасет ”;

String str2 = str1.concat(“мир”);

System.out.println(str2); //“Красота спасет мир”

System.out.println(str1); //“Красота спасет ”

  1.  Оптимизация строковых операций

Наиболее распространенной из строковых операций является операция слияния строк с помощью оператора +. Надо отметить, что такие операции требуют больших затрат памяти. Рассмотрим пример:

String s1 = “Произвольная строка – ”;

String s2 = “Присоединенная строка”;

String s3 = s1 + s2;

В данном случае создается три объекта: один с исходным текстом, второй – с присоединяемым, третий содержит обе части текста. Такой способ слияния не является оптимальным, так как каждый из создаваемых объектов требует выделения памяти. Для повышения эффективности программы рекомендуется использовать класс StringBuffer, который работает аналогично буферу обмена.

StringBuffer sb = new StringBuffer(52);

sb.append(“Произвольная строка – ”);

sb.append(“Присоединенная строка”);

String s3 = sb.toString();

В данном фрагменте программы метод append() присоединяет новую запись к старой записи, а метод toString() преобразует ее в строку.

  1.  Извлечение части строки

Для извлечения из строки определенной ее части (подстроки) следует вызвать метод String.substring(), в качестве параметров которого необходимо указать начало и длину подстроки.

int start = 6;

int end = 11;

String greetings = “Hello World!”;

String substr = greetings.substring(start, end);

System.out.println(substr); // “World”

  1.  Поиск текста

Для поиска первого вхождения подстроки в строку необходимо использовать метод indexOf, для поиска последнего – lastIndexOf() класса String. Указанные методы возвращают позицию (порядковый номер) первого символа искомой строки.

int index;

String greetings = “Hello World!”;

index = greetings.indexOf(“e”); // index = 1

index = greetings.lastIndexOf(“o”); // index = 7

index = greetings.lastIndexOf(“x”); // index = -1

  1.  Проверка на наличие записи в начале или в конце текста

Если вам необходимо узнать, начинается ли (или заканчивается) определенный текст указанной строкой, нужно использовать метод startsWith() (или endsWith()) класса String. Оба метода возвращают значение типа boolean, соответствующего результату выполнения операции:

String str = “Hello from Universe”;

boolean result = str.startsWith(“Hell”);   // true

boolean result = str.endsWith(“Universe”); // true

  1.  Извлечение символа из строки

Для извлечения символа из строки достаточно использовать метод charAt() класса String, в котором нужно указать позицию символа в строке:

char c = greetings.charAt(6); //‘W’ из “Hello World”

  1.  Замена символов в строке

Для замены символов в строке необходимо использовать метод replace() класса String. Он имеет два параметра. Первый соответствует тому, что заменять; второй – чем заменять. Например:

// Заменяет букву «о» на букву «а» в строке greetings.

String newString = greetings.replace(“o”, “a”);

  1.  Замена части строки

Для замены части строки можно воспользоваться несколькими из уже представленных методов класса String: indexOf(), substring() и методов класса StringBuffer:

// замена части строки

static String replace(String str, String pattern, String replace) {

int start = 0;

int pos = 0;

StringBuffer result = new StringBuffer();

while((pos = str.indexOf(pattern, start)) >= 0) {

 result.append(str.substring(start, pos));

 result.append(replace);

 start = pos + pattern.length();

}

 result.append(str.substring(start));

 return result.toString();

}  // replace(String, String, String)

  1.  Изменение регистра всех букв в строке

Для замены всех букв в строке строчными или прописными служат методы toLowerCase() и toUpperCase() класса String.

String greetings = “Hello World”;

String lower = greetings. toLowerCase();

//hello world

String upper = greetings. toUpperCase();

//HELLO WORLD

  1.  Слияние строк

Для слияния строк можно использовать не только оператор +, но также метод concat() класса String.

String greetings = “Hello”;

greetings + = “ “;

greetings. concat(“World!”);

  1.  Преобразование строки в числовой тип

Если нужно преобразовать строку в какой-нибудь числовой тип, необходимо использовать статические методы parseXXX() (здесь XXX – название числового типа) классов числовых типов – Integer, Long, Float и Double.

double d = Double.parseDouble(“421.5e10”);

float f = Float.parseFloat(“421.5”);

long l = Long.parseLong(“421”);

int i = Integer.parseInt(“421”);

  1.  Преобразование простых типов в строковый

Преобразование простых типов данных в строковый тип можно осуществить двумя способами. Неявный способ основан на применении оператора слияния (+) строк.

// Использование оператора слияния +

String s;

s = “ ” + true;  // true

s = “ ” + ((byte) 0x12);  // 18

s = “ ” + ((byte) 0xFF);  // -1

s = “ ” + ‘a’;  // a

s = “ ” + ((short) 132);  //  132

s = “ ” + 987;  // 987

s = “ ” + 987L;  // 987

s = “ ” + 9.87F;  // 9.87

s = “ ” + 9.87D;  // 9.87

Прямой метод основан на вызове метода valueOf() класса String.

// Использование метода String. valueOf()

String str = String. valueOf(true);   // true

str = String. valueOf((byte) 0x12);   // 18

str = String. valueOf((byte) 0xFF);   // -1

str = String. valueOf(‘a’);   // a

str = String. valueOf((short) 132);   // 132

str = String. valueOf(987);   // 987

str = String. valueOf(987L);   // 987

str = String. valueOf(9.87F);   // 9.87

str = String. valueOf(9.87D);   // 9.87

Порядок преобразования числа в строку может быть основан и на использовании метода toString():

Class IntString {

public static void main (String[] args) {

 // преобразование целого числа в строку

 int intValue = 101;

String stringValue = Integer.toString(intValue);

System.out.println(stringValue);

}

}

  1.  Перевод текста в кодировку Unicode и UTF-8

Строки записываются в Java в кодировке Unicode. Когда нам понадобится сохранить строку в файл через Интернет, необходимо преобразовать строку в UTF-8. Эту кодировку можно использовать в различных системах:

try {

// перевод текста в массив байтов UTF-8 из Unicode

 String string = “abc\u5639\u563b”;

byte[] utf8 = string.getBytes(“UTF-8”);

 // преобразование массива байтов UTF-8

// в текст кодировки Unicode

 string = new String(utf8, “UTF-8”);

} catch (UnsupportedEncodingException e) {

}

Для того чтобы «восстановить» первоначальный вид текста в целевой системе, она должна поддерживать платформу UTF-8. Иначе будет вызвано исключение UnsupportedEncodingException.


 

А также другие работы, которые могут Вас заинтересовать

24913. Виды юридических лиц и их классификация 30.5 KB
  ГК предусмотрены следующие формы НКО: потребительский кооператив; общественные религиозные организации и их объединения; фонды; учреждения; ассоциации и союзы коммерческих и некоммерческих организаций. Закон о НКО помимо указанных форм предусматривает: государственные корпорации например Объединенная Авиастроительная Корпорация во главе которой С.Иванов; некоммерческие партнерства; автономные НКО. Также в зависимости от прав участников учредителей ЮЛ делятся: на собственников в отношении которых участники учредители...
24914. Возникновение и прекращение юридических лиц. Правоспособность юридического лица 62.5 KB
  Правоспособность юридического лица Участниками гражданских правоотношений являются не только физические лица граждане но и юридические лица организации специально создаваемые для участия в гражданском обороте. несколько способов порядков создания юридических лиц: явочнонормативный исключает необходимость получения предварительного разрешения органов публичной власти на создание юридического лица. В таком порядке создается большинство юридических лиц разрешительный порядок связан с необходимостью получения предварительного...
24915. Понятие и правовое положение хозяйственных (торговых) обществ и товариществ 64.5 KB
  Хозяйственные торговые далее – хозяйственные товарищества и общества являются традиционной наиболее распространенной в обычном имущественном обороте формой коллективного предпринимательства. Товарищества и общества имеют много общих черт: 1 они являются коммерческими организациями созданными на добровольной как правило договорной основе на началах членства корпоративных 2 они наделяются законом общей правоспособностью 3 они становятся едиными и единственными собственниками имущества образованного за счет вкладов учредителей...
24916. Гражданско-правовое положение государственных и муниципальных унитарных предприятий 49.5 KB
  Далее для всех унитарных предприятий употребляю аббревиатуру ФГУП но понимаем что это не только федеральные но и субъектов федерации и муниципальные. ФГУП обладает имуществом которое является неделимой собственностью ее учредителя. ФГУП может учредить только одно юр. Устав сдолжен содержать сведения о деятельности собственнике и органе осуществляющем его полномочия перечень и порядок формирования и использования фондов на которые делится имущество ФГУП направления использования прибыли.
24918. Понятие и правовой статус некоммерческих организаций 59.5 KB
  Учредители НКО Учредителями некоммерческой организации в зависимости от ее организационноправовых форм могут выступать полностью дееспособные граждане и или юридические лица. В состав органов управления иностранных неправительственных НКО не могут входить государственные и муниципальные служащие если иное не установлено международным договором.1 ФЗ об НКО Органы управления НКО Высшими органами управления некоммерческими организациями в соответствии с их учредительными документами являются: коллегиальный высший орган управления для...
24919. Публично-правовые образования как субъекты гражданских правоотношений 48 KB
  К числу публичноправовых образований участвующих в гражданских правоотношениях относятся Российская Федерация субъекты РФ и муниципальные образования ст. Поэтому государство и другие публичноправовые образования в гражданскоправовых отношениях выступают на равных началах с иными их участниками гражданами и юридическими лицами п. Особенности гражданской правосубъектности публичноправовых образований В качестве субъектов гражданского права государство и иные публичноправовые образования обладают гражданской правоспособностью и...
24920. Объекты гражданских прав: понятие, виды 48.5 KB
  Объекты гражданских прав: понятие виды Объекты гражданских правоотношений это различные материальные в том числе вещественные и нематериальные идеальные блага либо процесс их создания составляющие предмет деятельности субъектов гражданского права. Закон может регулировать только поведение людей направленное на данные объекты а не их сами поэтому различие между разными объектами ГП в их режиме а не в их физических свойствах. Объекты ГП шире понятия объектов гражданского оборота поскольку имеются объекты ГП полностью их этого...
24921. Гражданско-правовой режим движимого и недвижимого имущества 36.5 KB
  Гражданскоправовой режим движимого и недвижимого имущества В соответствии со ст. Регистрация прав на движимые вещи не требуется кроме случаев указанных в законе. Движимые вещи по общему правилу не подлежат регистрации имеющей значение для гражданского оборота. Техническая регистрация некоторых движимостей может влиять лишь на осуществление прав на них но не на их возникновение.