Объект представляет (моделирует) конкретную сущность: вещь реального мира или абстрактное понятие, например, автомобиль, студента, товар в магазине, банковский счет, событие в календаре, процесс заказа в интернет-магазине, число, строку, список, прямоугольник и т. п.
Класс — это шаблон (форма) для создания объектов (экземпляров класса).
Объект — это экземпляр класса, который обладает конкретным состоянием и поведением.
- Состояние — это данные объекта, которые описывают его текущие характеристики (свойства, атрибуты). Состояние хранится в полях.
- Поведение — это действия, которые объект может выполнять. Поведение определяется методами.
Если класс — это шаблон (форма), то объект — это то, что создано по этому шаблону (форме).
Класс состоит из объявления и тела. Класс объявляется с помощью ключевого слова class.
// Класс, экземпляры которого представляют прямоугольники
// Объявление класса
public class Rectangle {
// Тело класса
}Статический контекст:
- Статический контекст включает поля и метода, принадлежащие классу.
- Статические поля и методы определены для всех экземпляров классов одинаково.
- Статические поля инициализируются при загрузке класса в JVM.
Нестатический контекст:
- Нестатический контекст включает поля и метода, принадлежащие объекту (экземпляру класса).
- Каждый объект имеет свою копию нестатических полей и методов.
- Нестатические поля инициализируются при создании объекта.
Переменная экземпляра (нестатическое поле) — это переменная, объявленная непосредственно в теле класса; представляет некоторую характеристику объектов этого класса.
Объявление поля включает тип данных и имя.
public class Rectangle {
// Координаты базовой точки (левого верхнего угла)
int x, y;
// Ширина и высота
int width, height;
// Цвет
Color color;
}Переменной экземпляра может быть присвоено начальное значение.
public class Rectangle {
// Координаты базовой точки (левого верхнего угла)
int x = 0, y = 0;
// Ширина и высота
int width = 100, height = 100;
// Цвет
Color color = Color.BLACK;
}В случае, когда поле не инициализируется явно, ему автоматически присваивается значение по умолчанию в зависимости от его типа данных.
public class DefaultValuesExample {
// ПРИМИТИВНЫЕ ТИПЫ
byte defaultByte; // 0
short defaultShort; // 0
int defaultInt; // 0
long defaultLong; // 0L
float defaultFloat; // 0.0f
double defaultDouble; // 0.0d
char defaultChar; // '\u0000' (нулевой символ)
boolean defaultBoolean; // false
// ССЫЛОЧНЫЕ ТИПЫ
String defaultString; // null
Object defaultObject; // null
int[] defaultArray; // null
}Локальные переменные НЕ инициализируются автоматически
Блоки инициализации экземпляра — это специальные блоки кода, которые выполняются при создании объекта.
public class Rectangle {
// Переменные экземпляра
int x, y; // Координаты базовой точки
int width, height; // Ширина и высота
Color color; // Цвет
// Блок инициализации экземпляра
{
x = 0; y = 0;
color = Color.BLACK;
}
}Завершенные переменные экземпляра — это переменные экземпляра, которым не могут присваиваться никакие другие значения после их инициализации.
- Объявляются с ключевым словом
final - Должны инициализироваться только явным образом.
public class Rectangle {
// Переменные экземпляра
int x, y; // Текущие координаты базовой точки
int width, height; // Ширина и высота
Color color; // Цвет
// Завершенные переменные экземпляра
final int startX = 0, startY = 0; // Начальные координаты базовой точки
}Метод экземпляра класса — это функция или процедура, объявленная в теле класса и определяющая алгоритм работы с объектами этого класса.
Метод состоит из объявления и тела. Объявление метода включает возвращаемый тип данных, имя и список параметров. В случае, когда метод ничего не возвращает, возвращаемый тип данных указывается ключевым словом void.
public class Rectangle {
// Поля
int x, y;
int width, height;
Color color = Color.BLACK;
// Вычислить площадь
int area() {
// Вернуть значение, соответсвующее возвращаемомум типу данных
return width * height;
}
// Нарисовать прямоугольник в графическом контексте
void draw(Graphics g) {
g.setColor(color);
g.fillRect(x, y, width, height);
}
// Передвинуть
void move(int x, int y) {
// Здесь происходит скрытие полей локальными переменными
this.x = x;
this.y = y;
}
// Масштабировать ширину и высоту пропорционально
void scale(double factor) {
if (factor > 0.0) {
width *= factor;
height *= factor;
}
}
}return — это инструкция управления потоком выполнения, которая завершает выполнение метода и возвращает управление вызывающему коду.
Для методов с возвращаемым типом данных отличным от void инструкция return возвращает значение этого типа данных.
public class ReturnValueExample {
// Метод с возвращаемым типом данных int
public int add(int a, int b) {
return a + b; // Возвращает значение примитивного типа int
}
public static void main(String[] args) {
ReturnValueExample example = new ReturnValueExample();
// Вызов метода экземпляра example.add
// После возврата значения из метода example.add,
// переменной sum присваивается его значение
int sum = example.add(5, 3);
System.out.println("Sum: " + sum);
}
}Досрочное завершение void метода:
// Void метод с явным return
public void printIfPositive(int number) {
if (number <= 0) {
System.out.println("Number is not positive");
return; // Досрочное завершение метода
}
System.out.println("Positive number: " + number);
// return; // Неявный return в конце
}Передача по значению для примитивных типов (передается копия значения):
public class PrimitiveParameters {
// Метод получает КОПИЮ значения
public static void modifyPrimitive(int number) {
number = number * 2; // изменяется копия
System.out.println("Inside method: number = " + number);
}
public static void main(String[] args) {
int original = 10;
System.out.println("Before method: original = " + original);
modifyPrimitive(original); // передается копия значения
System.out.println("After method: original = " + original);
}
}Передача по значению для ссылочных типов (передается копия ссылки):
public class ReferenceParameters {
// Метод получает КОПИЮ ссылки на объект
public static void modifyArray(int[] array) {
array[0] = 100; // изменяется содержимое объекта
System.out.println("Inside method: array[0] = " + array[0]);
}
public static void changeReference(int[] array) {
array = new int[]{999, 888, 777}; // изменяется копия ссылки
System.out.println("Inside method: new array[0] = " + array[0]);
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
System.out.println("Before modifyArray: numbers[0] = " + numbers[0]);
modifyArray(numbers);
System.out.println("After modifyArray: numbers[0] = " + numbers[0]);
System.out.println("\nBefore changeReference: numbers[0] = " + numbers[0]);
changeReference(numbers);
System.out.println("After changeReference: numbers[0] = " + numbers[0]);
}
}Перегрузка методов позволяет объявлять в одном классе несколько методов с одинаковыми именами, но разными списками параметров.
public class Rectangle {
// Поля
int x, y;
int width, height;
// Масштабировать ширину и высоту пропорционально
void scale(double factor) {
if (factor > 0.0) {
width *= factor;
height *= factor;
}
}
// Масштабировать ширину и высоту раздельно
void scale(double wFactor, double hFactor) {
if (wFactor > 0.0)
width *= wFactor;
if (hFactor > 0.0)
height *= hFactor;
}
}Переменное число аргументов (varargs) — это механизм, который позволяет методу принимать произвольное количество аргументов одного типа. Это альтернатива созданию перегруженных методов или передаче массива.
public class VarargsExample {
// Метод с varargs
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
public static void main(String[] args) {
// Разные способы вызова
System.out.println(sum()); // 0
System.out.println(sum(1)); // 1
System.out.println(sum(1, 2)); // 3
System.out.println(sum(1, 2, 3, 4)); // 10
// Можно передать массив
int[] arr = {5, 6, 7};
System.out.println(sum(arr)); // 18
}
}Компилятор преобразует varargs в массив:
// Если вы пишете:
public void method(String... strings)
// То компилятор преобразует этот код в:
public void method(String[] strings)В методе может быть только один varargs-параметр и он должен быть последним:
public void method(String prefix, int... numbers)this — это ключевое слово, которое представляет собой ссылку на текущий объект класса; указывает на тот объект, для которого в данный момент вызывается метод.
Ключевое слово this доступно только в нестатическом контексте.
public class Rectangle {
// Поля
int x, y;
int width, height;
// Вычислить площадь прямоугольника
int area() {
// Здесь ключевое слово this используется явно,
// хотя это не обязательно
return this.width * this.height;
}
}Ключевое слово this необходимо использовать в случае
скрытия полей локальными переменными.
public class Rectangle {
// Поля
int x, y; // Координаты базовой точки прямоугольника
int width, height;
// Переместить прямоугольник в точку с координатами x, y
void move(int x, int y) {
// Здесь поля x, y скрыты локальными переменными x, y,
// поскольку имена параметров x, y совпадают с именами полей x, y
this.x = x; // Обращение к полю x через this
this.y = y; // Обращение к полю y через this
}
}Конструкторы служат для создания объектов с заданным начальным состоянием. Имя конструктора должно совпадать с именем класса, в котором он объявлен.
public class Rectangle {
// Поля
int x, y;
int width, height;
Color color;
// Конструктор
Rectangle(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
// Методы
}Инициализация переменных экземпляра выполняется при его создании в следующем порядке:
- Поля экземпляра
- Блоки инициализации
- Конструкторы
В одном классе можно объявить несколько конструкторов с разными списками параметров.
public class Rectangle {
// Поля
int x, y;
int width, height;
Color color;
// Конструкторы
Rectangle(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
Rectangle(int x, int y, int width, int height) {
// Вызов перегруженного конструктора
this(x, y, width, height, Color.BLACK);
}
Rectangle(int width, int height) {
// Вызов перегруженного конструктора
this(0, 0, width, height, Color.BLACK);
}
// Методы
}Объекты класса создаются с помощью ключевого слова new, после которого следует вызов одного из доступных конструкторов.
public class MyMainClass {
public static void main(String[] args) {
Rectangle rect1 = new Rectangle(0,0, 100, 200);
Rectangle rect2 = new Rectangle(100,200);
Rectangle rect3 = new Rectangle(10,20, 100, 100, Color.RED);
}
}С объектами можно взаимодействовать через их доступные поля и методы.
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class MyMainClass {
public static void main(String[] args) {
// Создать прямоугольник
Rectangle rect = new Rectangle(0,0, 400, 500);
// Задать цвет
rect.color = Color.RED;
// Переместить прямоугольник
rect.move(200, 300);
// Уменьшить прямоугольник
rect.scale(0.5);
// Создать изображение и нарисовать на нем прямоугольник
BufferedImage image = new BufferedImage(1000, 1000,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
rect.draw(g);
try {
File file = new File("image.png");
ImageIO.write(image, "png", file);
} catch (IOException e) {
e.printStackTrace();
}
}
}Задание 5-1 — 1 балл
- Разработать класс верхнего уровня
Rectangleв пакетеru.isu.math.graphicsдля представления прямоугольников. В классе должны быть определены нестатические поля (координаты базовой точки, ширины и высота ограничивающей рамки, угол поворота, цвет заливки и цвет контура), нестатические методы (перемещения, поворота и масштабирования эллипса, вычисления площади эллипса) и конструкторы. Должна быть перегрузка методов и конструкторов. - Разработать отдельный Main-класс в пакете
ru.isu.math.graphicsс main-методом, в котором необходимо создать несколько объектов классаRectangleс помощью доступных конструкторов и через доступное поведение (перемещение, поворот, масштабирование) объектов классаRectangleизменить их состояние. Вычислить площади созданных прямоугольников. - Продемонстрировать работу отладчика в IDE. Установить точку останова в вашем коде. Запустить отладчик. Показать какие значения имеют локальные переменные в момент останова. Сделать один или несколько шагов так, продемонстрировать изменение значений локальных переменных при пошаговом выполнении кода. Установить курсор в некоторой строке вашего кода и выполнить код до этой строки; показать какие значения имеют локальные переменные в этот момент. Возобновить выполнение программы в обычном режиме.
Задание 5-2 — 1 балл
- Добавить класс верхнего уровня
Ellipseв пакетru.isu.math.graphicsдля представления эллипсов. В классе должны быть определены нестатические поля (координаты базовой точки, ширины и высота ограничивающей рамки, угол поворота, цвет заливки и цвет контура), нестатические методы (перемещения, поворота и масштабирования эллипса, вычисления площади эллипса) и конструкторы. Должна быть перегрузка методов и конструкторов. - Разработать отдельный Main-класс в пакете
ru.isu.math.graphicsс main-методом, в котором необходимо создать несколько объектов классаRectangleи объектов классаEllipseи нарисовать соответствующие им прямоугольники и эллипсы в файле изображения формата PNG.
Задание 5-3 — 2 балла
- Разработать приложение с интерфейсом командной строки (CLI) для создания и управления простыми графическими фигурами с возможностью экспорта результата в растровое изображение.
- Программа должна поддерживать создание двух типов фигур: прямоугольники (
Rectangle) и эллипсы (Ellipse). - Программа должна позволять перемещать выбранной фигуры на заданное смещение по осям X и Y.
- Программа должна позволять увеличивать или уменьшать размер существующей фигуры в заданное количество раз.
- Программа должна сохранять все созданные фигуры в файл изображения в формате PNG.
- Сопроводить исходный код Javadoc-комментариями и сгенерировать HTML-документацию с помощью команды javadoc.
- Собрать проект в виде запускаемого JAR-файла и продемонстрировать его работу.
Поддерживаемые команды CLI:
- Создание фигур
create rectangle <x> <y> <width> <height>create ellipse <x> <y> <width> <height>- Пример:
create rectangle 50 50 100 200— создает прямоугольник с вершиной в (50,50), шириной 100 и высотой 200. - После создания фигура получает уникальный числовой идентификатор (ID). Этот ID используется для управления фигурой в последующих командах.
- Перемещение фигур
move <id> <dx> <dy>- Пример:
move 1 10 -5— перемещает фигуру с ID=1 на 10 пикселей вправо и на 5 пикселей вверх.
- Масштабирование фигур
scale <id> <factor>- Пример:
scale 1 1.5— увеличивает фигуру с ID=1 в 1.5 раза. - Пример:
scale 2 0.5— уменьшает фигуру с ID=2 в 2 раза.
- Экспорт в изображение
export <filename.png>- Пример:
export my_drawing.png— сохраняет изображение в файлmy_drawing.pngв текущей директории.
- Прочие команды
list— выводит в консоль список всех фигур с их ID, типами и параметрами.exit— завершает работу приложения.
- Объясните: как устроен ваш класс?
- Выделите фрагмент вашего код, соответствующий объявлению класса?
- Выделите фрагмент вашего код, соответствующий телу класса?
- Какие переменные экземпляра объявлены в вашем классе?
- Какие нестатические поля есть в вашем классе?
- Какие типы данных имеют переменные экземпляра в вашем классе?
- Как вы инициализировали переменные экземпляра?
- Какие нестатические методы есть в вашем классе?
- Выделите фрагмент вашего кода, соответствующий объявлению нестатического метода?
- Выделите фрагмент вашего кода, соответствующий телу нестатического метода?
- Используете ли вы перегрузку методов?
- Есть ли в вашем коде одноименные методы с различными сигнатурами?
- Какой список параметров имеет тот или иной метод?
- Какие типы данных имеют передаваемые в метод параметры?
- Какой возвращаемый тип данных имеет тот или иной метод?
- Куда передает управление инструкция перехода
returnв вашем коде? - Какие конструкторы есть в ваше классе?
- Используете ли вы перегрузку конструкторов?
- Какую задачу выполняют ваши конструкторы?
- Какой список параметров имеет тот или иной конструктор?
- Есть ли у конструктора возвращаемый тип данных?
- Есть ли в вашем коде скрытие полей локальными переменными?
- Обращаетесь ли вы нестатическим полям через ключевое слово
this? - Как вы используете ключевое слово
thisпри перегрузке конструкторов? - Можно ли в вашем случае обойтись без ключевого слова
this, если ДА, то как? - Как вы создаете объекты вашего класса?
- Как вы объявляете переменные, значениями которых являются ссылки на объекты ваших классов?
- Что следует после оператора
newв вашем коде? - Как вы обращаетесь к полям объектов вашего класса?
- Как вы обращаетесь к методам объектов вашего класса?
