Наследование позволяет создавать новые классы на основе существующих, расширяя состояние и поведение объектов новыми свойствами и методами соответственно.
Суперкласс (Базовый класс) --- это класс, от которого наследуются другие классы.
В Kotlin, классы по умолчанию являются завершенными final
, что означает, что они не могут быть унаследованы. Чтобы разрешить наследование, класс должен быть помечен ключевым словом open
.
// Суперкласс для представления графических фигур
open class Shape {
var x: Int = 0
var y: Int = 0
fun move(dx: Int; dy: Int) {
x += dx
y += dy
}
}
Подкласс (Производный класс) --- это класс, который наследует свойства и методы от базового класса.
Подкласс создается с помощью ключевого слова class
, за которым следует имя класса и двоеточие, а затем имя суперкласса.
// Подкласс для представления прямоугольников
class Rectangle: Shape {
var width: Int = 1
var height: Int = 1
fun draw(Graphics2D g2d) {
g2d.fillRect(x, y, width, height)
}
}
В Kotlin методы и свойства, которые могут быть переопределены в подклассах, должны быть помечены ключевым словом open
. В подклассе они переопределяются с помощью ключевого слова override
.
// Суперкласс для представления графических фигур
open class Shape {
var x: Int = 0
var y: Int = 0
// Откытое для переопределения в подклассах свойство
open val defaultColor : Color = Color.BLACK
// Откытый для переопределения в подклассах метод
open fun draw(g2d: Graphics2D) {
}
}
// Подкласс для представления прямоугольников
class Rectangle: Shape() {
var width: Int = 1
var height: Int = 1
// Переопределение свойства, унаследованного от суперкласса
override val defaultColor : Color = Color.RED
// Переопределение метода, унаследованного от суперкласса
override fun draw(Graphics2D g2d) {
g2d.color = defaultColor
g2d.fillRect(x, y, width, height)
}
}
Член класса, помеченный override
, доступен для переопределения в производных классах. Чтобы сделать его завершенным (т.е. запретить возможность его переопределения), в объявление должен быть включен модификатор final
.
open class Rectangle() : Shape() {
// ...
final override fun draw() {
g2d.fillRect(x, y, width, height)
}
}
При наследовании суперкласса, подкласс может использовать первичный конструктор суперкласса для инициализации той части начального состояния создаваемых объектов, которая определена в суперклассе.
// Суперкласс для представления графических фигур с первичным конструктором
open class Shape (
var x: Int = 0,
var y: Int = 0
) {
open val defaultColor : Color = Color.BLACK
open fun draw(g2d: Graphics2D) {
}
}
// Подкласс для представления прямоугольников с первичным конструктором
class Rectangle(
x: Int = 0,
y: Int = 0,
var width: Int = 1,
var height: Int = 1
) : Shape(x, y) {
override val defaultColor : Color = Color.RED
override fun draw(g2d: Graphics2D) {
g2d.color = defaultColor
g2d.fillRect(x, y, width, height)
}
}
При наследовании суперкласса, подкласс может использовать вторичные конструкторы суперкласса для инициализации той части начального состояния создаваемых объектов, которая определена в суперклассе.
// Суперкласс для представления графических фигур со вторичным конструктором
abstract class Shape {
var x: Int = 0
var y: Int = 0
// Вторичный конструктор
..
constructor(x: Int, y: Int) {
this.x = x
this.y = y
}
abstract fun draw(g2d: Graphics2D)
}
// Подкласс для представления прямоугольников со вторичным конструктором
class Rectangle: Shape {
var width: Int = 1
var height: Int = 1
// Вторичный конструктор
constructor(x: Int, y: Int, width: Int, height: Int): super(x, y) {
this.width = width
this.height = height
}
override fun draw(g2d: Graphics2D) {
g2d.fillRect(x, y, width, height)
}
}
При создании объектов подклассов, параметры передаются через конструктор подкласса в конструктор суперкласса.
fun main() {
val rectangle = Rectangle(50, 50, 200, 100)
rectangle.draw()
}
Наследование позволяет создавать иерархии классов, где общие свойства и методы выносятся в суперклассы, а специфичные — в подклассы. Это упрощает код и делает его более модульным.
fun main() {
val rect = Rectangle(250, 250, 10, 20)
// Создаем растровое изображение размером 400x300 пикселей
val image = BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB)
// Получаем графический контекст для рисования на изображении
val g2d = image.createGraphics()
// Вывод прямоугольника на графический контекст
rect.draw(g2d)
}
Абстрактные классы — это классы, которые не могут быть инстанцированы напрямую, а предназначены для наследования. Они могут содержать абстрактные методы (т.е. методы без реализации), которые должны быть реализованы в подклассах.
// Абстрактный суперкласс для представления графических фигур
abstract class Shape (
var x: Int = 0,
var y: Int = 0
) {
// Абстрактный метод
abstract fun draw(g2d: Graphics2D)
}
// Подкласс для представления прямоугольников
class Rectangle(
x: Int = 0,
y: Int = 0,
var width: Int = 1,
var height: Int = 1
) : Shape(x, y) {
// Определение абстрактного метода, унаследованного от суперкласса
override fun draw(g2d: Graphics2D) {
g2d.fillRect(x, y, width, height)
}
}
...
...
...
Часть I Создание базовой иерархии классов для представления графических фигур с использованием наследования
Требования:
-
Создайте абстрактный класс
AreaShape
для представления абстрактных площадных графических фигур:- Должны быть объявлены следующие свойства:
x
,y
координаты базовой точкиcolor
(цвет фигуры)
- Должен быть реализован конструктор
- Должен быть объявлен и реализован метод
move(dx: Int, dy: Int)
для перемещения фигуры на заданное расстояние
- Должен быть объявлен абстрактный метод
draw(g2d: Graphics2D)
для отрисовки фигуры на графическом контекстеarea()
для вычисления площади фигуры
- Должны быть объявлены следующие свойства:
-
Создайте класс
Rectangle
, расширяющий классAreaShape
, для представления прямоугольников:- Должны быть объявлены следующие свойства:
width
,height
ширина и высота
- Должны быть переопределены следующие методы:
draw(g2d: Graphics2D)
: отрисовывает прямоугольник на графическом контексте.area()
: возвращает площадь прямоугольника.
- Должны быть объявлены следующие свойства:
-
Создайте класс
Ellipse
, расширяющий классRectangle
, для представления эллипсов.- Должны быть переопределены следующие методы:
draw(g2d: Graphics2D)
: отрисовывает эллипс на графическом контексте.area()
: возвращает площадь эллипса.
- Должны быть переопределены следующие методы:
-
Создайте несколько графических фигур и вычислите их площадь
Часть II Создание расширенной иерархии классов для представления графических фигур с использованием наследования:
Требования:
-
Создайте абстрактный класс
Shape
для представления абстрактных графических фигур:- Должны быть объявлены следующие свойства:
x
,y
координаты базовой точкиangle
угол поворота (в градусах)strokeColor
(цвет контура фигуры)
- Должен быть реализован конструктор
- Должны быть объявлены и реализованы следующие методы:
move(dx: Int, dy: Int)
для перемещения фигуры на заданное расстояниеrotate(angle: Int)
для поворота фигуры на заданный угол (в градусах)
- Должен быть объявлен абстрактный метод
draw(g2d: Graphics2D)
для отрисовки фигуры на графическом контексте
- Должны быть объявлены следующие свойства:
-
Создайте абстрактный класс
AreaShape
, расширяющий классShape
, для представления абстрактных площадных графических фигур:- Должны быть объявлены следующие свойства:
width
,height
ширина и высота описанного прямоугольникаfillColor
(цвет заливки фигуры)
- Должен быть реализован конструктор
- Должны быть объявлены и реализованы следующие методы:
scale(factor: Double)
для масштабирования фигуры с общим фактором для двух осейscale(xFactor: Double, yFactor: Double)
для масштабирования фигуры с разными факторами
- Должны быть объявлены следующие абстрактные методы
draw(g2d: Graphics2D)
для отрисовки фигуры на графическом контекстеarea()
для вычисления площади фигуры
- Должны быть объявлены следующие свойства:
-
Создайте класс
Rectangle
, расширяющий классAreaShape
, для представления прямоугольников:- Должны быть переопределены следующие методы:
draw(g2d: Graphics2D)
: отрисовывает прямоугольник на графическом контексте.area()
: возвращает площадь прямоугольника.
- Должны быть переопределены следующие методы:
-
Создайте класс
Ellipse
, расширяющий классAreaShape
, для представления эллипсов.- Должны быть переопределены следующие методы:
draw(g2d: Graphics2D)
: отрисовывает эллипс на графическом контексте.area()
: возвращает площадь эллипса.
- Должны быть переопределены следующие методы:
-
Создайте класс
Line
, расширяющий классShape
, для представления эллипсов.- Должны быть объявлены следующие свойства:
x2
,y2
координаты конечной точки линии
- Должен быть переопределен метод:
draw(g2d: Graphics2D)
: отрисовывает линию на графическом контексте.
- Должны быть объявлены следующие свойства:
-
Создайте класс
Text
, расширяющий классShape
, для представления текста.- Должны быть объявлены следующие свойства:
text
текст
- Должен быть переопределен метод:
draw(g2d: Graphics2D)
: отрисовывает текст на графическом контексте.
- Должны быть объявлены следующие свойства:
-
Создайте несколько графических фигур и выведите их изображение в файл формата PNG.
- Должен быть создан по крайней мере один прямоугольник, один эллипс, одна линия, один текст:
- Необходимо отрисовать серию изображений прямоугольника, полученных в результате его масштабирования
- Необходимо отрисовать серию изображений эллипса, полученных в результате его перемещения.
- Необходимо отрисовать серию изображений линии, полученных в результате ее поворота.
- Необходимо отрисовать серию изображений текста, полученных в результате ее поворота.
Часть III Разработать приложение командной строки, которое позволяет рисовать три вида диаграмм (график, столбчатая, круговая).
Требования:
- Создайте абстрактный класс диаграмм
Chart
с абстрактным методомdraw()
. - Реализуйте три класса, наследующиеся от
Chart
:LineChart
(график),BarChart
(столбчатая диаграмма) иPieChart
(круговая диаграмма). - Каждый класс должен реализовывать метод
draw()
для рисования соответствующего типа диаграммы. - Создайте класс
ChartFactory
, который будет создавать объектыChart
в зависимости от типа диаграммы. - Реализуйте функцию
main()
, которая считывает входные данные, создает объектChart
с помощьюChartFactory
и вызывает методdraw()
. - Входные данные должны задаваться пользователем в командной строке.
- Пользователь должен иметь возможность настройки следующих параметров:
- Цвета используемые в диаграммах (для графиков и столбчатых диаграмм)
- Текстовые подписи осей координат (для графиков и столбчатых диаграмм)
- Размер диаграммы (для всех видов диаграмм)
- Легенда (для круговых диаграмм)
- Диаграммы должны выводиться на графический контекст, а их изображения должны сохраняться в файлы в формате PNG.
- Наследование
- Суперкласс / Подкласс
- Базовый класс / Производный класс
- Абстрактный класс
- Абстрактный метод
- Переопределение свойств
- Переопределение методов
- Полиморфизм