Книга Объектно-ориентированное программирование на Java. Платформа Java SE - читать онлайн бесплатно, автор Тимур Машнин. Cтраница 3
bannerbanner
Вы не авторизовались
Войти
Зарегистрироваться
Объектно-ориентированное программирование на Java. Платформа Java SE
Объектно-ориентированное программирование на Java. Платформа Java SE
Добавить В библиотекуАвторизуйтесь, чтобы добавить
Оценить:

Рейтинг: 0

Добавить отзывДобавить цитату

Объектно-ориентированное программирование на Java. Платформа Java SE

А именно, цикл for.

Этот цикл объединяет три важных момента для переменной счетчика:



Ее инициализацию, условие остановки, и выражение обновления.

Имейте в виду, что обновление выполняется после того, как выполняется тело цикла, а не раньше.

Для цикла for скобки являются обязательными, а также две точки с запятой внутри.

Фигурные скобки необходимы только в том случае, если есть более одного выражения в теле цикла.

Но это хорошая практика, чтобы всегда писать их.

Как вы видели, если в начальный момент условное выражение, управляющее циклом while, ложно, тело цикла вообще не будет выполняться.



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

Иначе говоря, существуют ситуации, когда проверку условия прерывания цикла желательно выполнять в конце цикла, а не в его начале.

И в Java есть именно такой цикл: do-while.

Этот цикл всегда выполняет тело цикла хотя бы один раз, так как его условное выражение проверяется в конце цикла.

В приведенном примере тело цикла выполняется до первой проверки условия завершения.

Мы уже видели оператор break в выражении switch.



Но оператор break также может прерывать любой цикл.

Предположим, у вас есть цикл.

И иногда желательно немедленно завершить цикл, не проверяя условие.

В таких случаях используется оператор break.

Оператор break немедленно завершает цикл, и управление программой переходит к следующему выражению, следующему за циклом.

Оператор break почти всегда используется вместе с выражением if else.

Также иногда желательно не прервать цикл, а пропустить код тела цикла и перейти к следующей итерации.



Оператор continue пропускает текущую итерацию цикла и когда выполняется оператор continue, управление программой переходит к концу цикла.

Затем проверяется условие, которое управляет циклом.

Оператор continue также почти всегда используется вместе с выражением if else.

Массивы


На почте мы могли арендовать ячейку, чтобы получать письма.



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

Ячейки обычно обозначаются последовательными номерами.

Ячейки или шкафчики могут быть разного размера.

В программировании мы видели переменные, которые позволяют хранить значения.

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

Однако в некоторых случаях нам может понадобиться упорядоченный набор значений одного и того же типа.

Например, когда мы хотим хранить оценки учеников класса, или температуры каждого дня месяца.

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

Как нам к этим переменным обращаться?

Мы привыкли свободно выбирать имена переменных.



И таким же образом мы можем дать имя массиву переменных.

Для обозначения местоположения одной переменной используется индекс.

Так, например, мы могли бы назвать массив a.

Предположим, что у него четыре элемента в четырех позициях.

Мы будем ссылаться на каждую позицию, добавляя индекс в квадратные скобки.

Обратите внимание, что мы начинаем с индекса 0 и увеличиваем его на единицу.

Здесь мы видим примеры массивов.



Массивы могут содержать разные типы значений, но в каждом массиве, тип является одинаковым для всех значений.

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

Надо помнить, что есть два шага при работе с массивами. Объявление массива и его создание.



Элементы в массиве можно получить с помощью индекса.

Мы не должны путать значение элемента с его индексом.

Еще одна вещь, которую следует помнить, это то, что первым элементом массива является элемент с индексом 0.

Таким образом, индексы начинаются с 0 и до длины массива минус 1.

Мы объявляем массив, указывая тип элементов, затем открываем и закрываем квадратные скобки, и затем указываем имя, которое мы выбрали для нашего массива.

После объявления, создавая массив с помощью ключевого слова new, мы физически резервируем для него место в памяти, как в почтовом отделении.

Мы также можем сделать это вместе: объявить и создать массив в одной строке.

Теперь мы можем хранить значения в разных позициях.

Как мы сохраняем значения?

Мы используем оператор присваивания, как раньше мы использовали его для переменных.



Имя массива с индексом используется, как мы раньше использовали идентификаторы переменных.

Мы также можем объявить, создать и инициализировать массив сразу, как мы видим здесь, в последней строке, используя фигурные скобки.

Обратите внимание, что в этом случае нам не нужно писать ключевое слово «new».

Теперь, если строки – это упорядоченные последовательности символов, вопрос, является ли строка и массив символов одним и тем же.

Это не так, хотя можно конвертировать одно в другое.



Другой вопрос заключается в том, может ли элемент массива быть массивом.

Здесь ответ да.

Таким образом, мы получаем то, что мы называем двумерными массивами.



Но возможны и многомерные массивы.

Таким образом, массивы – это упорядоченные последовательности элементов одно и того же типа.

И длина фиксируется при создании массива.

И элементы массива могут быть массивами.

Массивы и циклы for имеют нечто общее.

Массив состоит из последовательности данных, а цикл for выполняет выражения последовательно несколько раз подряд.

Здесь мы видим массив с четырьмя целыми числами от 0 до 3.



И ниже приведена структура цикла for, которая повторяет выражения четыре раза.

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

Например, если применить операцию возведения в степень 2 к целому числу 3, получим 9.



Теперь представьте, что мы хотим применить эту операцию ко всем целым числам в массиве.

Цикл for поможет нам последовательно брать все значения в массиве и возводить их в степень 2, начиная с индекса 0 до индекса 3.

Другой пример – сложить все числа в массиве.



Если вы хотите сделать это для любой длины массива, используйте x. length вместо 4.



Перебор элементов массива в цикле for, начиная с индекса 0 до длины массива, настолько распространен, что для этого существует специальный цикл for.



В этом цикле for мы можем проинструктировать переменную elem последовательно использовать все элементы массива.

Представление данных и типы данных


Давайте посмотрим под капот калькулятора или компьютера, и посмотрим, как мы можем представлять данные.

И начнем с простого.

Давайте посмотрим на логические значения, потому что там есть только два значения, true и false.

Цифровые компьютеры состоят из электроники, которая может находиться только в одном из двух состояний.

Триггер – это базовая единица, которая может оставаться либо в одном положении, либо в другом.



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

В действительности 1 может иметь нулевое напряжение, а другое состояние – пять вольт.

Но мы можем произвольно интерпретировать их как 0 и 1.

Поэтому мы можем сказать, что триггер может хранить один бит информации.

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

И мы, опять же, можем произвольно присвоить 0 false и 1 true.

Итак, мы говорим, что нам нужен бит, чтобы сохранить логическое значение.

Теперь, если у вас есть два триггера, мы можем сохранить два бита.

Если мы соберем их вместе, у нас будет четыре возможных комбинации: 0—0, 0—1, 1—0 и 1—1, поскольку каждый из них может иметь состояние 0 или 1 независимо друг от друга.



И если мы возьмем восемь триггеров, чтобы сохранить восемь бит, у нас будет 2 в степени 8 различных комбинаций.

То есть 256 комбинаций в целом.



Что мы можем с ними делать?

Восемь бит называется байт.

Итак, что мы можем сделать с байтом?

Мы можем представить 256 различных чисел.

Например, натуральные числа от 0 до 255.

Мы также можем отображать 256 уровней красного, от черного до ярко-красного.

И мы можем получить любой цвет, составляя уровни красного, зеленого и синего.

Для каждого из этих компонентов мы используем один байт.

Таким образом, это всего три байта или 24 бита, что означает 2 в степени 24, что почти 17 миллионов цветовых комбинаций.

Звуки, фильмы, все представлено битами 0 и 1.

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

Наконец, мы можем также представлять отдельные символы, как те, которые есть у вас на клавиатуре, а также некоторые другие специальные символы.

Для этого существует множество кодировок.

Java использует кодировку юникода, использующую 16 бит.

Другие кодировки используют только восемь бит.

Таким образом, все в компьютере представлено битами.

Все сводится к нулям и единицам.

Давайте сосредоточимся на том, как мы представляем числа в двоичной форме битами.

С 1 байтом – 8 бит – мы можем сформировать 256 различных комбинаций, или 2 в степени 8.



Поэтому мы можем представить 256 различных чисел.

Это могут быть, например, натуральные числа от 0 до 255.

Но какая комбинация байт соответствует какому числу?

Давайте проанализируем систему, которую мы используем для представления чисел в нашей десятичной системе, которая использует 10 цифр, от 0 до 9.

Используем систему, основанную на весах.

Чем больше мы двигаемся влево, тем выше вес.



Когда мы пишем 972, мы имеем в виду 9 умножить на 100 плюс 7 умножить на 10 плюс 2.

Так как здесь основание 10, система исчисления называется десятичной.

Для двоичной системы исчисления тот же принцип, только основанием будет 2.



Соответственно, перевести число из двоичной системы в десятичную очень просто, нужно сложить получившийся ряд.



Перевести число из десятичной системы в двоичную тоже просто, нужно делить на 2 и записывать остаток.



Но как насчет отрицательных чисел? Нам тоже нужно работать с ними.

Неотрицательные числа, т. е. 0 и положительные числа – закодированы по-прежнему, где самый левый бит установлен в 0.



И у нас осталось семь бит.

Таким образом, мы можем иметь 2 в степени 7 различных неотрицательных чисел, а именно от 0 до 127.

Для отрицательных чисел они кодируются таким образом, что сумма отрицательного числа и его положительного аналога равна 2 в степени числа бит, т. е. восемь, или 256, или 1, а затем восемь 0.

Таким образом, с этим кодированием мы можем представлять, как положительные, так и отрицательные числа.

Теперь давайте сосредоточимся на Java.

Какие типы данных мы используем для целых чисел?

На самом деле это не один тип данных, а доступно несколько типов данных.



У нас есть тип данных, называемый «байт», который использует точно восемь бит – это и есть, один байт.

Мы можем представить цифры от -128 до 127, как мы только что видели.

Есть тип данных «short», который использует 16 бит и находится в диапазоне от -32 000 до плюс

32000.

Но основным типом данных, которым мы будем пользоваться, будет «int».

Здесь максимальное положительное число составляет более 2 миллиардов.

Если вам потребуются большие цифры, можно использовать «long» с 64 битами.

Для чисел с плавающей запятой есть два типа данных в Java: «float», который использует 32 бита, и «double», который использует 64 бита.



Рекомендуется использовать double, когда нужны числа с плавающей запятой.

Подводя итог, существует восемь примитивных типов данных в Java.

Два для представления нечисловых данных: boolean для булевых значений, true и false, и char – для представления одного символа.



И числовые типы данных.

int – это основной тип данных, который нужно запомнить для представления целых чисел.

И остальные байт, short, и long.

И double – это основной тип данных для чисел с плавающей запятой.

Другой тип – float.

Таким образом мы не можем работать с бесконечно большими числами или числами с бесконечной точностью.

Методы


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

Для каждого числа, вы вводите одно число, затем оператор умножения, а затем снова число.

И то же самое для другого числа и т. д.

Поэтому в калькуляторе было бы неплохо иметь программируемую кнопку, которая выполняет любую операцию, которую мы определим.

Это может быть квадрат или квадратный корень, или любые вычисления, которые нам понадобятся.



В Java также возможно определять пользовательские операции.

Но вместо того, чтобы называть их операциями, мы называем их методами.

Это является терминологией Java.

В других языках программирования они называются функциями или процедурами.

Метод – это вычисление, которому мы даем имя, так что мы можем вызывать его в любое время, когда нам нужно выполнить это вычисление.

Метод может зависеть от одного или любого числа параметров.

И метод может привести к какому-то результату или какому-то эффекту.

Рассмотрим метод вычисления квадрата числа.

Можно представить этот метод как черный ящик, который получает целое число в качестве входных данных и выводит другое целое число.



В математических терминах мы можем определить его как функцию следующим образом.

Мы дадим функции имя, например, square.

И эта функция принимает целое число как параметр и возвращает целое число.

Функция определяется следующим образом.

Если мы назовем аргумент или параметр как x, результат получается умножением x на x.

Теперь, как мы определим это в Java?

Сначала мы напишем что-то похожее на первую строку в математическом определении.

Но порядок немного другой.

Во-первых, мы пишем тип результата, затем имя метода, а затем в круглых скобках тип параметра и далее идентификатор параметра.

При этом у нас может быть несколько параметров.

Все это называется заголовком метода.

Затем мы напишем в фигурных скобках то, что мы должны сделать, чтобы вычислить результат.

И мы указываем, что это результат возврата, поместив ключевое слово return перед выражением.

Затем в фигурных скобках мы пишем вычисление, которое хотим выполнить.

И мы называем это телом метода.

Имя метода может быть любым допустимым идентификатором.

Но мы будем следовать соглашению, и напишем его с маленькой буквы.

И обычно это глагол.

Если нам нужно больше одного слова, мы будем писать каждое следующее слово с заглавной буквы.



Как мы видим здесь в isEmpty.

И рекомендуется, чтобы имя метода имело значение, чтобы другие могли легко понять, что здесь вычисляется.

Имена параметров мы также можем свободно выбирать.

Нам нужно дать имя параметру, потому что нам нужно обращаться к параметру в теле метода.



Но этот идентификатор является внутренним.

Если мы заменим его на другой идентификатор, мы не изменим метод.

Вместо x мы можем указать y в качестве идентификатора параметра.

Так как, по существу, x или y являются просто заполнителями для фактического параметра, который мы указываем при вызове метода.

Сколько входных параметров может иметь метод?



И что насчет результата?

Мы видели, как определить метод с одним параметром и одним результатом.

Можем ли мы также иметь больше параметров?

У нас может быть несколько параметров.



Здесь мы видим метод с двумя параметрами.

Обратите внимание, что они разделяются запятыми.

И у нас может быть еще больше параметров, разделенных запятыми.

Также у нас может не быть никаких параметров.



Теперь круглые скобки пустые.

В этом случае этот метод всегда возвращает одно и то же значение.

Или у нас может не быть никакого возвращаемого результата.



В этом случае мы пишем void как тип результата.

Это имеет смысл, например, если мы хотим что-то напечатать.

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

И о функциях, если возвращается результат.

Но в Java мы просто говорим о методах.

Наконец, мы можем иметь метод без параметров и без результатов.



Теперь мы рассмотрели все возможные случаи.

Область видимости переменных


В предыдущей лекции мы узнали, как определить метод.

И мы хотим знать, что происходит, когда мы его вызываем.

Возьмем снова метод, вычисляющий квадрат числа.



Он называется square и принимает одно значение и возвращает другое значение – квадрат числа.

Важно отметить, что определение метода идентифицирует два контекста – внутри и снаружи.

Внутри мы можем использовать параметры x или y или что угодно.

Но не снаружи.

Извне мы просто знаем название метода, параметры, и тип результата.

Как вычисляется метод, это вопрос внутреннего контекста.

В какой-то момент мы могли бы изменить тело метода.

Здесь мы видим альтернативный способ вычисления квадрата числа.



Но мы не знали бы этого извне, из контекста вызова.

Теперь давайте посмотрим, что происходит, когда мы вызываем метод с заданным значением.

Мы могли бы проанализировать, что происходит, когда мы вызываем square (3).



Но давайте сделаем немного интереснее.

Попробуем оценить выражение square (3) + square (4).

Чтобы получить результат суммы, сначала мы должны вычислить первый операнд, square (3).

И для этого мы перейдем к определению метода, где x теперь равно 3.

Это означает, что мы должны заменить все x на 3.

Таким образом, мы вычисляем 3 умножить на 3.

Результат будет – 9, и это то, что возвращает вызов метода.

9 теперь является значением первого операнда суммы.

Затем нам нужно вычислить значение для square (4).

Перейдем к определению метода, но теперь x равно 4.

3 больше не существует.

Поэтому мы заменяем все x на 4, и поэтому умножаем 4 на 4.

Этот вызов метода возвращает 16 вызывающему выражению.

Теперь у нас есть оба операнда, и мы можем сложить 9 и 16.

Во всех этих вычислениях важно отметить, что два вызова одного и того же метода полностью независимы.

Мы использовали x с двумя независимыми значениями.

Сначала 3, а затем 4.

И когда мы использовали 4, 3 уже не существовало.

Каждый раз, когда мы делаем новый вызов, параметры создаются со значениями вызова.

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

Мы использовали идентификаторы или имена в разных целях: для переменных, для методов, для параметров метода и т. д.

Теперь возникает вопрос: если у нас есть переменная с именем «x», а затем у нас есть метод с параметром.

Можно ли назвать этот параметр как «х»?

Или будет какая-то несовместимость?

Можем ли мы использовать одно и то же имя в разных контекстах?

Давайте рассмотрим пример.