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

Пример

В предыдущем примере автомобиля, методы moveCar и turnCar просто распечатывали сообщение на экране о том, что методы должны делать, вместо выполнения реальных действий.

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

И мы дадим этому классу новое имя Car2.





Здесь у нас есть экземпляр переменной для хранения информации о владельце, как и раньше.

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

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

Кроме того, мы хотим описать больше полезных свойств автомобилей в этом классе.

В наше время предпочитают покупать экологически чистые автомобили.

Поэтому полезной информацией является расход топлива.

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

Наконец, мы хотим знать, сколько бензина в баке.

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

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

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

Давайте посмотрим на конструкторы класса для Car2 объектов.







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

Конструктор, который не имеет параметров, просто использует все настройки по умолчанию.

Я хочу отметить, что, если конструктор не определен внутри класса, Java будет предоставлять конструктор по умолчанию для класса от его суперкласса.

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

Как и второй конструктор в предыдущем примере, второй конструктор здесь имеет один параметр типа String.

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

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

Ключевое слово new здесь показывает, что создается новый объект типа ColorImage.

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

И здесь есть третий конструктор. Поскольку gasMileage может измениться, так как автомобиль стареет.

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

Этот конструктор принимает два параметра, один типа String, другой типа double.

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

Давайте теперь посмотрим на методы Сar2.







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

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

Текущее положение получается методом getX для объекта carImage с помощью оператора точки.

А расстояние перемещения указывается в качестве параметра.

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

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

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

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

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

Текущая ориентация получается методом getRotation для объекта carImage с помощью оператора точки.

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

Давайте назовем этот метод addGas.

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

Помните, что мы вычислили gasUsed в методе перемещения.

В выражении внутри метода addGas добавим значение gasUsed к gasInTank, а затем присвоим результат обратно к переменной gasInTank.

Как вы думаете, это будет работать?

То, что вы обнаружите, это компилятор будет выдавать ошибку: "Невозможно найти символ – переменную gasUsed".

Почему это так?

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

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

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

Так что любая ссылка на нее вне метода moveForward вызовет ошибку.

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

В некотором смысле, это как кратковременная память.

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







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

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