Инкапсуляция — это принцип ООП, который заключается в объединении данных и методов, работающих с этими данными, в единый объект, и сокрытии внутренней реализации от внешнего доступа.
Согласно этому принципу в классе необходимо выделить открытую часть и закрытую часть.
Пакеты — это механизм для организации классов в логические группы, что помогает избежать конфликтов имен и управлять доступом.
Объявление пакета:
// Самая первая инструкция (в начале файла .java)
package com.company.project.module;
public class MyClass {
// код класса
}Физически пакет является иерархией каталогов, а имя пакета соответствует структуре каталогов:
com/
└── company/
└── project/
└── module/
└── MyClass.java
Обычно, имя пакета начинается с доменного имени той организации, в которой разрабатывается советующий исходный код, записанного в обратном порядке. Такое именование пакетов позволяет избежать конфликты пространств имен.
Стандартная схема именования пакета:
com.[company].[project].[module].[submodule]
Пакеты могут иметь общую начальную часть в структуре каталогов.
Например, имеем следующие классы:
package ru.isu.math.graphicaleditor;
public class GraphicalEditorApp {
// код класса
}package ru.isu.math.graphicaleditor.graphics;
public abstract class Shape {
// код класса
}package ru.isu.math.graphicaleditor.graphics;
public class Rectangle extends Shape {
// код класса
}В этом случае имеем два разных пакета:
ru.isu.math.graphicaleditor
ru.isu.math.graphicaleditor.graphics
Соответствующая структура каталогов будет выглядеть следующим образом:
ru/
└── isu/
└── math/
└── graphicaleditor/
├── GraphicalEditorApp.java
└── graphics/
├── Shape.java
└── Rectangle.java
Внутри одного пакета нет необходимости импортировать одни классы этого пакета в другие классы этого же пакета. Если пакеты разные, то чтобы использовать классы одного пакета в классах другого пакета, их необходимо импортировать.
package ru.isu.math.graphicaleditor;
// Импорт всех классов из вложенного пакета
import ru.isu.math.graphicaleditor.graphics.*;
public class GraphicalEditorApp {
// код класса
}Есть четыре уровня доступа к полям, методам и конструкторам:
| Где доступно? | Закрытый (private) |
Пакетный (по умолчанию) | Защищенный (protected) |
Открытый (public) |
|---|---|---|---|---|
| Класс | да | да | да | да |
| Пакет | нет | да | да | да |
| Пакет и подклассы | нет | нет | да | да |
| Любой класс | нет | нет | нет | да |
Есть три модификатора доступа:
private— закрытый уровень доступа;protected— защищенный уровень доступа;public— открытый уровень доступа.
Пакетный уровень применяется по умолчанию, поэтому не имеет модификатора.
К классам верхнего уровня возможно применить только два уровня доступа: открытый или пакетный (по умолчанию).
По умолчанию класс доступен только в своем пакете.
package ru.isu.math.graphicaleditor.graphics;
// Этот класс доступен только в пакете
// ru.isu.math.graphicaleditor.graphics
abstract class Shape {
// Код класса
}Публичный класс может быть доступен в любых других классах.
package ru.isu.math.graphicaleditor.graphics;
// Этот класс доступен только везде, где он импортирован
public class Rectangle extends Shape {
// Код класса
}Публичный класс может быть импортирован в классы других пакетов.
package ru.isu.math.graphicaleditor;
// Импорт всех публичных классов заданного пакета
impoprt ru.isu.math.graphicaleditor.graphics.*;
public class GraphicalEditorApp {
// код класса
public static void main(String[] args) {
// Используем класс Rectangle
Rectangle rect = new Rectangle();
// Попытка обратиться к классу Shape
// Shape[] shapes = {rect} // ОШИБКА!
}
}Закрытые поля и методы объявляются с модификатором private.
package com.company.project.module;
public class BaseClass {
// Закрытое поле доступно только внутри данного класса
private String secret;
// Закрытый метод доступен только внутри данного класса
private void printSecret() {
System.out.println(secret);
}
// Другие поля и методы
}Из любого другого класса доступ к закрытому полю и методу напрямую невозможен.
package com.company.project;
import com.company.project.module.BaseClass;
public class MainClass {
public static void main(String[] args) {
BaseClass bc = new BaseClass();
// Попытка обратиться к закрытому полю другого класса
String s = bc.secret; // ОШИБКА!
// Попытка обратиться к закрытому методу другого класса
String s = bc.printSecret(); // ОШИБКА!
}
}Защищенные поля и методы объявляются с модификатором prоtected.
package com.company.project.module;
public class BaseClass {
// Защищенное поле
prоtected String secret;
// Другие поля и методы
}Подкласс имеет доступ к защищенным полям и методам, объявленным в суперклассе.
package com.company.project.othermodule;
import com.company.project.module.BaseClass;
public class DerivedClass extends BaseClass {
// Защищенный метод
prоtected void printSecret() {
System.out.println(secret);
}
// Другие поля и методы
}Но за пределами пакета защищенные поля и методы уже не доступны.
package com.company.project; // Другой пакет
import com.company.project.module.BaseClass;
import com.company.project.othermodule.DerivedClass;
public class MainClass {
public static void main(String[] args) {
BaseClass bc = new BaseClass();
// Попытка обратиться к защищенному полю другого класса
String s = bc.secret; // ОШИБКА!
DerivedClass dc = new DerivedClass();
// Попытка обратиться к защищенному методу другого класса
String s = dc.printSecret(); // ОШИБКА!
}
}Пакетные поля и методы объявляются без модификатора (по умолчанию).
package com.company.project.module;
public class BaseClass {
// Пакетное поле
String secret;
// Другие поля и методы
}Подкласс имеет доступ к защищенным полям и методам, объявленным в суперклассе.
package com.company.project.module; // Тот же самый пакет
public class OtherClass {
// Пакетный метод
void printSecret() {
System.out.println(secret);
}
// Другие поля и методы
}Но за пределами пакета пакетные поля и методы уже не доступны.
package com.company.project; // Другой пакет
public class MainClass {
public static void main(String[] args) {
BaseClass bc = new BaseClass();
// Попытка обратиться к пакетному полю другого класса
String s = bc.secret; // ОШИБКА!
OtherClass oc = new OtherClass();
// Попытка обратиться к пакетному методу другого класса
String s = oc.printSecret(); // ОШИБКА!
}
}Публичные поля и методы объявляются с модификатором public.
package com.company.project.module;
public class BaseClass {
// Публичное поле
public String unsecretedId;
// Публичный метод
public void printUnsecreted() {
System.out.println(unsecretedId);
}
// Другие поля и методы
}Публичные поля и методы доступны везде где доступен сам класс, в котором они объявлены.
package com.company.project;
import com.company.project.module.BaseClass;
public class MainClass {
public static void main(String[] args) {
BaseClass bc = new BaseClass();
// Можно обратиться к публичному полю другого класса
String s = bc.unsecretedId;
// Можно обратиться к публичному методу другого класса
bc.printUnsecreted();
}
}Как правило, любое нестатическое поле объявляется закрытым (private) и сопровождается парой открытых (public) методов доступа (аксессоры): геттером (для чтения значения) и сеттером (для редактирования значения).
Добавление методов доступа в класс Shape:
import java.awt.*;
public abstract class Shape {
// Закрытые поля
private int x, y; // Координаты базовой точки
private Color color; // Цвет
// Методы доступа к закрытым полям (аксессоры)
// Геттер для поля x
public int getX() {
return x;
}
// Сеттер для поля x
public void setX(int x) {
if (x >= 0 && x <= 1000)
this.x = x;
}
// Геттер для поля y
public int getY() {
return y;
}
// Сеттер для поля y
public void setY(int y) {
if (y >= 0 && y <= 1000)
this.y = y;
}
// Геттер для поля color
public Color getColor() {
return color;
}
// Сеттер для поля color
public void setColor(Color color) {
if (color != null)
this.color = color;
}
// Конструктор
Shape(int x, int y, Color color) {
setX(x); // Задать значение поля x через сеттер
setY(y); // Задать значение поля y через сеттер
setColor(color); // Задать значение поля color через сеттер
}
// Метод для перемещения фигуры
void move(int dx, int dy) {
int newX = getX(); // Получить значение поля x через геттер
int newY = getY(); // Получить значение поля x через геттер
newX += dx; // Вычислить новое значение x-координаты
newY += dy; // Вычислить новое значение y-координаты
setX(newX); // Задать значение поля x через сеттер
setY(newY); // Задать значение поля y через сеттер
}
// Другие поля и методы
// Нарисовать фигуру в графическом контексте
abstract void draw(Graphics2D g);
}В подклассах доступ к закрытым членам суперкласса осуществляется через аксессоры.
public class Rectangle extends Shape {
// Поля, методы и конструкторы
public static Rectangle copy(Rectangle rect) {
Rectangle copy = new Rectangle();
// Инструкции для копирования координат базовой точки
int x = rect.getX(); // Получить значение поля x через геттер
int y = rect.getY(); // Получить значение поля y через геттер
copy.setX(x); // Присвоить значение полю x через сеттер
copy.setY(y); // Присвоить значение полю y через сеттер
// Другие инструкции для копирования ширины, высоты, угла поворота и пр.
return copy;
}
}Во всех других классах доступ к закрытым членам класса осуществляется через аксессоры.
public class MainClass {
public static void main(String[] args) {
Rectangle rect = new Rectangle();
// Инструкции
int rectX = rect.getX(); // Получить значение поля x через геттер
int rectY = rect.getY(); // Получить значение поля y через геттер
rect.setX(10); // Присвоить значение полю x через сеттер
rect.setY(10); // Присвоить значение полю y через сеттер
// Другие инструкции
}
}Класс Object является корневым классом для всех остальных классов. Каждый класс прямо или косвенно наследуется от класса Object.
// Все эти объявления эквивалентны
class MyClass { }
class MyClass extends Object { }Класс Object имеет несколько полезных методов, которые следует переопределять в его подклассах.
Метод toString возвращает строковое представление объекта.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Переопределение метода toString
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}Cтроковое представление объекта часто используют в процессах отладки приложения и журналирования состояния объектов.
Person person = new Person("John", 25);
System.out.println(person); // Вывод: Person{name='John', age=25}Без переопределения метода toString строковое состояние объекта задается именем его класса и адресом объектной ссылки.
Person person = new Person("John", 25);
System.out.println(person); // Вывод: Person@15db9742Метод equals сравнивает объекты на равенство.
Метод hashCode возвращает хэш-код объекта.
public class Person {
private String name;
private int age;
private String email;
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Переопределение equals вручную
@Override
public boolean equals(Object obj) {
// Проверка на ссылочное равенство
if (this == obj) {
return true;
}
// Проверка на null
if (obj == null) {
return false;
}
// Проверка на совпадение классов
if (getClass() != obj.getClass()) {
return false;
}
// Приведение типа
Person other = (Person) obj;
// Сравнение полей
// Сравнение age (примитивный тип)
if (age != other.age) {
return false;
}
// Сравнение name (ссылочный тип)
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
// Сравнение email (ссылочный тип)
if (email == null) {
if (other.email != null) {
return false;
}
} else if (!email.equals(other.email)) {
return false;
}
return true;
}
// Переопределение метода hashCode вручную
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
return result;
}
}Можно переопределить методы equals и hashCode с помощью утилиты Objects:
import java.util.Objects;
public class Person {
private String name;
private int age;
private String email;
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Переопределение equals с Objects.equals()
@Override
public boolean equals(Object obj) {
// 1. Проверка на ссылочное равенство
if (this == obj) return true;
// 2. Проверка на null и совпадение классов
if (obj == null || getClass() != obj.getClass()) return false;
// 3. Приведение типа
Person person = (Person) obj;
// 4. Сравнение полей с Objects.equals() для ссылочных типов
return age == person.age &&
Objects.equals(name, person.name) &&
Objects.equals(email, person.email);
}
// Переопределение hashCode с Objects.hash()
@Override
public int hashCode() {
return Objects.hash(name, age, email);
}
}Если метод equals возвращает true при сравнении двух объектов, то метод hashCode() должен возвращать одинаковые значения для этих объектов, и, наоборот, если метод hashCode возвращает разные значения для двух объектов, то метод equals должен возвращать false при их сравнении.
public class MainClass {
public static void main(String[] args) {
// Создаем два РАВНЫХ объекта
Person person1 = new Person("Иван", 25, "ivan@math.isu.ru");
Person person2 = new Person("Иван", 25, "ivan@math.isu.ru");
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
// Проверяем контракт
boolean equalsResult = person1.equals(person2);
int hashCode1 = person1.hashCode();
int hashCode2 = person2.hashCode();
boolean hashCodesEqual = (hashCode1 == hashCode2);
System.out.println("\nПроверка контракта:");
System.out.println("person1.equals(person2): " + equalsResult);
System.out.println("person1.hashCode(): " + hashCode1);
System.out.println("person2.hashCode(): " + hashCode2);
System.out.println("hashCode1 == hashCode2: " + hashCodesEqual);
System.out.println("\n✓ Контракт выполняется: equals=true → hashCode равны");
}
}Вложенные классы — это классы, объявленные внутри другого класса. Они помогают логически сгруппировать классы, улучшить инкапсуляцию и сделать код более читаемым.
public class OuterClass {
private static String outerStaticField = "Static field";
private String outerInstanceField = "Instance field";
static class StaticNestedClass {
public void print() {
System.out.println(outerStaticField); // Доступ только к статическим полям
// System.out.println(outerInstanceField); // Ошибка компиляции!
}
}
}
// Использование
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
nested.print();public class OuterClass {
private String outerField = "Outer field";
class InnerClass {
public void print() {
System.out.println(outerField); // Доступ к полям внешнего класса
}
public void modifyOuterField() {
outerField = "Modified from inner class";
}
}
public InnerClass createInner() {
return new InnerClass();
}
}
// Использование
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
// или
OuterClass.InnerClass inner2 = outer.createInner();// Статический вложенный класс
OuterClass.StaticNestedClass staticNested = new OuterClass.StaticNestedClass();
// Внутренний класс
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();Вложенный класс может иметь любой из уровень доступа:
- Закрытый (объявление с модификатором доступа
private) - Защищенный (объявление с модификатором доступа
protected) - Пакетный (объявление без модификатора доступа)
- Публичный (объявление с модификатором доступа
public)
Строитель (англ. Builder) — это порождающий шаблон проектирования, который позволяет создавать сложные объекты пошагово.
Строитель для абстрактного класса Shape
import java.awt.*;
public abstract class Shape {
private int x, y;
private Color color;
// Геттеры и сеттеры
// Защищенный конструктор для использования строителем
protected Shape(ShapeBuilder builder) {
setX(builder.x);
setY(builder.y);
setColor(builder.color);
}
// Базовый строитель
public static abstract class ShapeBuilder {
protected int x = 0;
protected int y = 0;
protected Color color = Color.BLACK;
// Методы для установки параметров
public ShapeBuilder x(int x) {
this.x = x;
return this;
}
public ShapeBuilder y(int y) {
this.y = y;
return this;
}
public ShapeBuilder color(Color color) {
this.color = color;
return this;
}
public ShapeBuilder position(int x, int y) {
this.x = x;
this.y = y;
return this;
}
// Абстрактный метод для построения конкретной фигуры
public abstract Shape build();
}
// Другие методы
// Переопределение методов toString, equals, hashCode
}Builder для класса Rectangle
import java.awt.*;
public class Rectangle extends Shape {
private int width;
private int height;
private double rotation;
// Геттеры и сеттеры
// Закрытый конструктор для использование строителем
private Rectangle(RectangleBuilder builder) {
super(builder);
this.width = builder.width;
this.height = builder.height;
this.rotation = builder.rotation;
}
// Публичный конструктор по умолчанию
public Rectangle() {
super(new RectangleBuilder().x(0).y(0).color(Color.BLACK));
this.width = 10;
this.height = 10;
this.rotation = 0;
}
// Строитель
public static class RectangleBuilder extends ShapeBuilder {
private int width = 10;
private int height = 10;
private double rotation = 0;
public RectangleBuilder width(int width) {
this.width = width;
return this;
}
public RectangleBuilder height(int height) {
this.height = height;
return this;
}
public RectangleBuilder size(int width, int height) {
this.width = width;
this.height = height;
return this;
}
public RectangleBuilder rotation(double rotation) {
this.rotation = rotation;
return this;
}
// Переопределене методов базового строителя
@Override
public RectangleBuilder x(int x) {
super.x(x);
return this;
}
@Override
public RectangleBuilder y(int y) {
super.y(y);
return this;
}
@Override
public RectangleBuilder color(Color color) {
super.color(color);
return this;
}
@Override
public Rectangle build() {
return new Rectangle(this);
}
}
// Статический метод для создания строителя
public static RectangleBuilder builder() {
return new RectangleBuilder();
}
// Другие методы
// Переопределение методов toString, equals, hashCode Создание объектов пошагово с помощью строителя.
public class MainClass {
public static void main(String[] args) {
// Создание прямоугольника через строитель
Rectangle rect = Rectangle.builder()
.x(10)
.y(20)
.color(Color.RED)
.width(100)
.height(50)
.rotation(0.0)
.build();
System.out.println(rect);
}
}7-1 — 1 балл
- Разработать абстрактный класс
Shapeв пакетеru.isu.math.graphicsдля представления графических фигур. - В классе
Shapeдолжны быть объявлены ЗАКРЫТЫЕ нестатические поля (координаты левого верхнего угла ограничивающей рамки, ширина и высота ограничивающей рамки, цвет контура, цвет заливки, угол поворота). - В классе
Shapeдолжны быть реализованы методы доступа (геттеры и сеттеры) ко всем ЗАКРЫТЫМ нестатическим полям. - В классе
Shapeдолжны быть объявлены завершенные статические поля: допустимые (минимальные и максимальные) значения координат левого верхнего угла ограничивающей рамки, ширины и высоты ограничивающей рамки, угла поворота. - В классе
Shapeдолжно контролироваться присваивание значений нестатическим полям в СЕТТЕРАХ, а именно значения координат левого верхнего угла ограничивающей рамки, ширины и высоты ограничивающей рамки, угла поворота должны принадлежать диапазонам допустимых значений, определенных соответствующими глобальными константами. - В классе
Shapeдолжны быть объявлены нестатические завершенные методы (перемещения, вращения, масштабирования). - В классе
Shapeдолжны быть объявлены абстрактные методы (вычисления площади, отрисовки на графическом контексте) - В классе
Shapeдолжны быть конструкторы с аргументами, которые задают значения нестатических полей через СЕТТЕРЫ. - Разработать класс
Rectangleв пакетеru.isu.math.graphicsдля представления прямоугольников: класс должен быть унаследован от класса «Shape». - В классе
Rectangleдолжны быть объявлены и реализованы методы, переопределяющие абстрактные методы, унаследованные от классаShape. - Конструкторы подкласса
Rectangleдолжны содержать явные вызовы конструктора суперклассаShape. - В классе
Rectangleдолжны быть переопределены методыtoString,equalsиhashCode, унаследованные от классаObject. - Разработать отдельный Main-класс в пакете
ru.isu.math.graphicsс main-методом, в котором необходимо создать несколько объектов классаRectangleс помощью доступных конструкторов и через доступное поведение (перемещение, поворот, масштабирование) объектов классаRectangleизменить их состояние. Вычислить площади созданных прямоугольников.Rectangleизменить их состояние. Вычислить площади созданных прямоугольников. - Продемонстрировать строковое представление объекта класса
Rectangle, возвращаемое методомtoString. - Продемонстрировать выполнение контракта методов
equalsиhashCodeна примере сравнения двух эквивалентных по состоянию объектов классаRectangle. - Продемонстрировать работу отладчика в IDE. Установить точку останова в вашем коде. Запустить отладчик. Показать какие значения имеют локальные переменные в момент останова. Сделать один или несколько шагов так, продемонстрировать изменение значений локальных переменных при пошаговом выполнении кода. Установить курсор в некоторой строке вашего кода и выполнить код до этой строки; показать какие значения имеют локальные переменные в этот момент. Возобновить выполнение программы в обычном режиме.
7-2 — 1 балл
- Разработать класс
Ellipseв пакетеru.isu.math.graphicsдля представления эллипсов: класс должен быть унаследован от классаShape. - В классе
Ellipseдолжны быть реализованы методы, переопределяющие абстрактные методы, унаследованные от классаShape. - В классе
Ellipseдолжны быть переопределены методыtoString,equalsиhashCode, унаследованные от классаObject. - Конструкторы подкласса
Ellipseдолжны содержать явные вызовы конструктора суперклассаShape. - Разработать класс
Triangleдля представления треугольников: класс должен быть унаследован от классаShape; в классе должно быть переопределение абстрактных методов из классаShape. - В классе
Triangleдолжны быть реализованы методы, переопределяющие абстрактные методы, унаследованные от классаShape. - В классе
Triangleдолжны быть переопределены методыtoString,equalsиhashCode, унаследованные от классаObject. - Конструкторы подкласса
Triangleдолжны содержать явные вызовы конструктора суперклассаShape. - Разработать отдельный Main-класс в пакете
ru.isu.math.graphicsс main-методом, в котором необходимо создать несколько объектов классовRectangle,Ellipse,Triangleи нарисовать соответствующие им прямоугольники, эллипсы, треугольники в файле изображения формата PNG. - Добавить в класс
Rectangleстатический метод для конвертирования прямоугольников в эллипсы. - Добавить в класс
Ellipseстатический метод для конвертирования эллипсов в прямоугольники. - Продемонстрировать строковые представления объектов классов
EllipseиTriangle, возвращаемые соответствующими переопределениями методаtoString. - Продемонстрировать выполнение контракта методов
equalsиhashCodeна примере сравнения двух эквивалентных по состоянию объектов классовEllipseиTriangle. - Разработать отдельный Main-класс в пакете
ru.isu.math.graphicsс main-методом, в котором необходимо создать несколько объектов классаRectangle, объектов классаEllipseи объектов классаTriangle. Добавить созданные объекты в массив типаShape[]. Перебрав данный массив, нарисовать соответствующие им прямоугольники, эллипсы и треугольники в файле изображения формата PNG; при этом сделать серию изображений с масштабированием, перемещением и вращением фигур (каждое изображения серии сохранить в отдельный файл формата PNG).
7-3 — 2 балла
- Разработать приложение с интерфейсом командной строки (CLI) для создания и управления простыми графическими фигурами (прямоугольники, эллипсы, треугольники) с возможностью экспорта результата в растровое изображение.
- Дополнить классы
Shape,Rectangle,EllipseиTriangleСТРОИТЕЛЯМИ для пошагового создания их объектов. - Программа должна поддерживать ПОШАГОВОЕ создание трех типов фигур: прямоугольники, эллипсы и треугольники с помощью СТРОИТЕЛЕЙ. (Фигуры должны быть представлены объектами соответственно классов
Rectangle,EllipseиTriangle, описанных в двух предыдущих заданиях.) - Программа должна позволять перемещать выбранной фигуры на заданное смещение по осям X и Y.
- Программа должна позволять вращать выбранную фигуру на заданный угол в градусах.
- Программа должна позволять увеличивать или уменьшать размер существующей фигуры в заданное количество раз.
- Программа должна сохранять все созданные фигуры в файл изображения в формате PNG.
- Сопроводить исходный код Javadoc-комментариями и сгенерировать HTML-документацию с помощью команды javadoc.
- Собрать проект в виде запускаемого JAR-файла и продемонстрировать его работу.
Поддерживаемые команды:
- Создание фигур
create rectangle <x> <y> <width> <height> <color>create ellipse <x> <y> <width> <height> <color>create rectangle <x> <y> <side> <color>create ellipse <x> <y> <side> <color>- Пример:
create rectangle 50 50 100 #FF0000— создает прямоугольник с вершиной в (50, 50), шириной 100 и высотой 100, заполненный красным цветом. - После создания фигура получает уникальный числовой идентификатор (ID). Этот ID используется для управления фигурой в последующих командах.
- Перемещение фигур
move <id> <dx> <dy>- Пример:
move 1 10 -5— перемещает фигуру с ID=1 на 10 пикселей вправо и на 5 пикселей вверх.
- Вращение фигур
rotate <id> <angle>- Пример:
rotate 1 90— вращает фигуру с ID=1 на 90 градусов.
- Масштабирование фигур
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— завершает работу приложения.
- Как представлен пакет физически?
- Как пакет определяет пространство имен?
- Какое полное имя имеет ваш класс?
- Почему в имени пакета используется доменное имя, записанное в обратном порядке?
- Какие уровни доступа вы использовали при реализации ваших классов?
- Выделите модификаторы доступа в вашем коде?
- Какой уровень доступа имеет то или иное поле?
- Какой уровень доступа имеет тот или иной метод?
- Какой уровень доступа имеет тот или иной конструктор?
- Какие методы доступа вы реализовали?
- Выделите объявления аксессоров в вашем коде?
- Какая пара геттера и сеттера отвечает за доступ к тому или иному закрытому полю?
- Как можно реализовать доступ READ-ONLY к полям?
- Как вы реализовали валидацию значений в сеттерах?
- Объясните применяемый вами уровень доступа, как он ограничивает доступ, где будет доступен класс, поле, метод или конструктор, к которому применяется этот уровень доступа?
- Применяете ли вы уровень доступа по умолчанию?
- Наследуют ли ваши классы методы класса
Object? - Какие методы класса
Objectвы переопределили? - Что возвращает метод
toString? - Что возвращает метод
equals? - Что возвращает метод
hashCode? - Объясните контракт пары методов
equals-hashCode? - Используется ли вашем коде полиморфизм?
- Используется ли вашем коде полиморфизм?
- Используется ли вашем коде инкапсуляция?
- Есть ли в вашем коде вложенные классы?
- Есть ли в вашем коде внутренние классы?
- Используете ли вы строителей для пошагового создания объектов?
- Создаете ли вы объекты пошагово с помощью строителей?
- Как вы ограничили доступ к вашим вложенным классам?