Книга: Основы программирования с Java
Назад: Пример
Дальше: Демонстрация примера

Демонстрация примера

Откроем среду IntelliJ IDEA и загрузим проект Сar2.





Мы увидим определение Сar2.

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

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

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

И создадим экземпляр объекта Сar2 с первым конструктором, используя настройки по умолчанию.

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

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

Обратите внимание, что автомобиль перемещается, и консоль также отображает, что 0,2 л бензина было использовано и количество топлива, оставшегося в баке теперь 9.8 вместо 10.







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







Здесь мы увидим, что gasInTank теперь 19,8, а не просто 9.8, как и прежде.

Давайте посмотрим на метод makeTurn и повернем машину, скажем на 90 градусов.







Автомобиль вращается, как и ожидалось.

Все до сих пор кажется прекрасным.

Давайте вернемся к методу moveForward и переместим автомобиль на 100 единиц.







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

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

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

Вопросы

Задача

Описание

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

В этой задаче вы должны улучшить движение автомобиля. Перемещайте машину вперед или назад с учетом ориентации автомобиля. Вы можете сделать это, изменив как х положение (с помощью setX), так и положение у (с помощью setY).

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







Как указано на схеме, должны быть вычислены косинус (COS) и синус (SIN) угла поворота.

Это может быть сделано с помощью методов cos и sin, определенных в Java классе Math (http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html).

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







Ответ:

double rotationInRadians = Math.toRadians(rotationInDegrees);

double rotationInRadians = 22.0 / 7.0 * rotationInDegrees / 180;

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

Учитывая расстояние, на которое мы хотим двигать автомобиль, и угол поворота в радианах, расстояние движения в направлениях Х и Y можно рассчитать следующим образом:







Ответ:

double distX = dist * Math.cos(rotationInRadians);

double distY = dist * Math.sin(rotationInRadians);

Правила области видимости

В этом разделе мы продолжим обсуждение объектно-ориентированного программирования.

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

Затем мы начнем знакомиться с операторами ветвления, в том числе с выражениями if-else и switch.

Давайте сначала рассмотрим некоторые примеры, чтобы проиллюстрировать использование различных типов переменных, их видимость и срок их действия, исходя из объектно-ориентированного подхода.

Давайте сначала посмотрим, что означает видимость переменной.







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

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

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

Например, евро может использоваться в Европе, доллары в США и юани в Китае.

Один и тот же термин в другом контексте может нести разный смысл.

Например, то, что вы можете получить за 100 долларов в Азии, очень отличается от того, что можно было бы получить за ту же сумму в долларах в США или Европе.

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

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

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

Скажем, если вы находитесь в Англии, вы, вероятно, имеете в виду Лондон в Великобритании.

Если вы находитесь в Канаде, вы, вероятно, говорите о Лондоне в провинции Онтарио.

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

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

Давайте рассмотрим правила видимости для различных типов переменных в Java.

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

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

Эти переменные объявляются вне методов и доступны из любой точки в классе, где они были объявлены.

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

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

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

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

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

А что, если у нас есть две переменные, объявленные с одним и тем же именем в программе.

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

Если такое объявление не найдено, делается попытка найти соответствующее объявление переменной в блоке его родителя.

Этот процесс будет повторяться до тех пор, пока область переменной не будет разрешена.

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

Давайте сначала посмотрим на простой пример, а именно класс BankAccount, который мы рассматривали ранее.







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

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







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

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

Здесь, методы deposit и withdraw имеют один параметр.

Один с именем dAmount и другой с именем wAmount.

Как описано в правилах видимости для переменных параметров, переменные параметров являются локальными переменными.

Они могут быть использованы только в соответствующих методах, так что методу deposit не будет разрешен доступ к wAmount и методу withdraw не разрешено обращаться к переменной dAmount.

Теперь, что будет, если мы изменим как dAmount, так и wAmount на одно и то же имя Amount.







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

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

Давайте откроем IntelliJ IDEA и посмотрим на выполнение программы.

Назад: Пример
Дальше: Демонстрация примера