С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233

Как правильно составить иерархию классов\интерфейсов?

22.02.2015, 21:43. Показов 3166. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сразу же просьба к модераторам не ругать за такой заголовок. Просто у меня не получается в двух словах описать суть проблемы.
Итак, на изображении моя первая попытка использования интерфейсов. А место где я застрял - класс MG_DrawingRenderable. Для начала опишу идею подробней: есть класс MG_Drawing, позволяющий работать с группой элементов, реализующих MG_I_DrawingElement. А так же есть класс MG_DrawingRenderable, который должен расширять MG_Drawing и уметь отображать на Graphics2D себя (свои элементы, реализующие MG_I_DRElement, дословно - элемент чертежа отображаемый ). Следовательно, элементы MG_I_DRElement это те же MG_I_DrawingElement только ещё с методом рисования. А класс MG_DrawingRenderable - тот же MG_Drawing, но так же с методом render(). Проблема в том, что класс MG_DrawingRenderable работает с расширенными версиями элементов MG_I_DrawingElement, с которыми работает класс MG_Drawing и если я наследую MG_DrawingRenderable от MG_Drawing, то нужно как-то указать это. Иначе в MG_DrawingRenderable наследуются методы, принимающие некорректные для этого класса объекты. А просто переопределить метод с изменением типа входных параметров нельзя.

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


На самом деле я просто хочу, чтобы кто-то проверил правильность структуры так как понятия не имею как используются интерфейсы и делал наугад ))
Миниатюры
Как правильно составить иерархию классов\интерфейсов?  
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.02.2015, 21:43
Ответы с готовыми решениями:

Java SE - Правильно ли я понимаю применение интерфейсов и абстрактных классов ?
Правильно ли я понимаю применение интерфейсов и абстрактных классов ? Созданы интерфейсы Move, Eat, Voice эти итерфесы extends интерфейс...

Массив интерфейсов, как представителей классов
Скажу сразу: мне не нужно, чтобы вы решили мне задание ! Мне нужна помощь в понимании самого задания. Смогу поговорить с преподавателем о...

Как вывести иерархию наследования классов(и объектов)?
По идее в java нет множественного наследования(исключая интерфейсы), значит можно как-то вывести всю иерархию объектов до Object? Во...

10
Почетный модератор
 Аватар для ildwine
6201 / 2963 / 1300
Регистрация: 04.03.2013
Сообщений: 5,797
Записей в блоге: 1
22.02.2015, 22:33
Напишите хоть 1 класс сюда... Будем от него скакать...
0
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233
25.02.2015, 10:46  [ТС]
А тут ничего сложного:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class MG_Drawing implements MG_I_Drawing {
    public final ArrayList<MG_I_DrawingElement> elements = new ArrayList<>();
 
    @Override
    public void addElement(MG_I_DrawingElement el) {
        this.elements.add(el);
    }
 
    @Override
    public ArrayList<MG_I_DrawingElement> getElements(){
        return this.elements;
    }
}
 
public interface MG_I_Drawing {
    public void addElement(MG_I_DrawingElement el);
    public ArrayList<MG_I_DrawingElement> getElements();
}
 
public interface MG_I_DrawingRenderable extends MG_I_Drawing, MG_I_Renderable{}
public interface MG_I_DRElement extends MG_I_DrawingElement, MG_I_Renderable {}
 
public interface MG_I_Renderable {
    public void render(Graphics2D g2d);
}
 
public class MG_DrawingRenderable extends MG_Drawing implements MG_I_DrawingRenderable{
    
    private final ArrayList<MG_I_DRElement> elements = new ArrayList<>();
 
    @Override
    public void addElement(MG_I_DrawingElement el) {}//это не подходит
 
    @Override
    public void addElement(MG_I_DRElement el) {}//на это ругается
 
    @Override
    public void render(Graphics2D g2d) {
        for (MG_I_Renderable rEls : this.elements) {
            rEls.render(g2d);
        }
    }
}
Добавлено через 20 часов 32 минуты
Что-то тону...

Добавлено через 21 час 44 минуты
Что, нет идей?

Добавлено через 31 минуту
Без интерфейсов всё работало почти идеально, а когда я решил их добавить, пришлось переделывать практически всю программу. При этом возникла такая путаница, что я сильно пожалел об этом. А всего-то нужно было в единственном классе использовать множественное наследование.

Добавлено через 3 часа 26 минут
Цитата Сообщение от x_Alex_x Посмотреть сообщение
Java
1
2
@Override
public void addElement(MG_I_DRElement el) {}//на это ругается
Хмм... Вы знаете, теперь такая запись не вызывает претензий у компилятора. Понятия не имею что произошло.

Добавлено через 13 часов 2 минуты
В общем, я рано радовался. Программа хоть и заработала, но остались дыры, про которые я говоил выше.
Написал демку, чтобы проблема была ещё понятней. Прошу дописать закомментированный класс.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
public class Demo {
 
    public static void main(String[] args) {
        MG_Drawing d = new MG_Drawing();
        d.addElement(new MG_DrawingPoint(10, 20, d));
 
        for (MG_I_DrawingElement el : d.getElements()) {
            System.out.println(el.toString());
        }
    }
 
}
 
interface MG_I_Drawing {
 
    public void addElement(MG_I_DrawingElement el);
 
    public ArrayList<MG_I_DrawingElement> getElements();
}
 
class MG_Drawing implements MG_I_Drawing {
 
    public final ArrayList<MG_I_DrawingElement> elements = new ArrayList<>();
 
    @Override
    public void addElement(MG_I_DrawingElement el) {
        this.elements.add(el);
    }
 
    @Override
    public ArrayList<MG_I_DrawingElement> getElements() {
        return this.elements;
    }
}
 
//class MG_DrawingRenderable ...{
//...
//}
//
interface MG_I_DrawingElement {
 
    public void setDrawing(MG_I_Drawing d);
 
}
 
abstract class MG_DrawingElement implements MG_I_DrawingElement {
 
    public MG_I_Drawing drawing = null;
 
    public MG_DrawingElement(MG_I_Drawing drawing) {
        this.setDrawing(drawing);
    }
 
    @Override
    public final void setDrawing(MG_I_Drawing d) {
        this.drawing = d;
    }
}
 
interface MG_I_DrawingPoint extends MG_I_DrawingElement {
 
}
 
class MG_DrawingPoint extends MG_DrawingElement implements MG_I_DrawingPoint {
 
    int x;
    int y;
 
    public MG_DrawingPoint(int x, int y, MG_I_Drawing drawing) {
        super(drawing);
        this.x = x;
        this.y = y;
    }
 
    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }
 
}
interface MG_I_DRPoint extends MG_I_DRElement, MG_I_DrawingPoint{
    
}
class MG_DRPoint extends MG_DrawingPoint implements MG_I_DRPoint {
 
    public MG_DRPoint(int x, int y, MG_I_Drawing drawing) {
        super(x, y, drawing);
    }
 
    @Override
    public void render() {
        System.out.println("точка "+super.toString()+" отображена.");
    }
    
}
 
interface MG_I_DrawingRenderable extends MG_I_Drawing, MG_I_Renderable {
 
    public void addElement(MG_I_DRElement el);
 
    public ArrayList<MG_I_DRElement> getElements(String groupName);
}
 
interface MG_I_Renderable {
 
    public void render();
}
 
interface MG_I_DRElement extends MG_I_DrawingElement, MG_I_Renderable {
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
26.02.2015, 09:34
Лучше опишите вашу задачу так, как она была вам поставлена. Построенная вами иерархия может быть совершенно верна, а может быть в корне неправильная. Без постановки задачи не понятно.

Когда что-то отрисовывается на ум сразу приходит множественная диспетчеризация.
0
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233
26.02.2015, 10:07  [ТС]
lemegeton, класс Drawing(чертёж) позволяет работать с группой объектов DrawingElement(точка, отрезок...) класс DrawingRenderable добавляет возможность этот чертёж отображать посредством отрисовывания расширенных (DRElement) элементов DrawingElement, умеющих теперь отрисовывать самих себя.
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
26.02.2015, 11:26
Лучший ответ Сообщение было отмечено x_Alex_x как решение

Решение

Да, похоже, что речь про диспетчеризацию. Чертеж должен всех отрисовывать.

Классическая задача.

В приложении изображение диаграммы классов.

На словах:

Есть интерфейс Drawable, общий для всех отрисовываемых фигур.
Есть интерфейс Canvas (полотно), умеющий отрисовывать каждую реализацию Drawable.

Есть SimpleTextOutputCanvas, который является реализацией канваса и реализовывает отрисовку конкретных фигур.
Есть Point и Line, которые позволяют отрисовывать себя через канвас.

Есть Drawing (чертеж), который содержит коллекцию Drawable и один Canvas, на котором это все отрисовывается.

Магия в том, что Point и Line отдают управление отрисовкой себя в Canvas.

Код:

Абстракции:
Drawable (отрисовываемое)

Java
1
2
3
public interface Drawable {
    void draw(Canvas canvas);
}


Canvas (полотно, на котором отрисовывается)

Java
1
2
3
4
public interface Canvas {
    public void draw(Point point);
    public void draw(Line line);
}


Реализации:
Point (точка)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Point implements Drawable {
 
    private final long x;
    private final long y;
 
    public Point(long x, long y) {
        this.x = x;
        this.y = y;
    }
 
    public long getX() {
        return x;
    }
 
    public long getY() {
        return y;
    }
 
    @Override
    public void draw(Canvas canvas) {
        // магия передачи управления тут
        canvas.draw(this);
    }
 
    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}


Line (линия)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Line implements Drawable {
 
    private final Point a;
    private final Point b;
 
    public Line(Point a, Point b) {
        this.a = a;
        this.b = b;
    }
 
    public Point getA() {
        return a;
    }
 
    public Point getB() {
        return b;
    }
 
    @Override
    public void draw(Canvas canvas) {
        // магия передачи управления тут
        canvas.draw(this);
    }
 
    @Override
    public String toString() {
        return "Line{" +
                "a=" + a +
                ", b=" + b +
                '}';
    }
}


SimpleTextOutputCanvas (простое полотно, выводящее фигуры текстом)
Java
1
2
3
4
5
6
7
8
9
10
11
public class SimpleTextOutputCanvas implements Canvas {
    @Override
    public void draw(Point point) {
        System.out.println(point);
    }
 
    @Override
    public void draw(Line line) {
        System.out.println(line);
    }
}


Чертеж, собирающий воедино отрисовывоемое и отрисовывающего (можно сделать более гибко):
Drawing
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Collection;
 
public class Drawing {
    private final Collection<Drawable> drawables;
    private final Canvas canvas;
 
    public Drawing(Collection<Drawable> drawables, Canvas canvas) {
        this.drawables = drawables;
        this.canvas = canvas;
    }
 
    public void draw() {
        for (final Drawable drawable : drawables) {
            drawable.draw(canvas);
        }
    }
 
}


Пример использования:
Launcher
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Arrays;
import java.util.Collection;
 
public class Launcher {
 
    public static void main(String[] args) {
        final Canvas canvas = new SimpleTextOutputCanvas();
        final Collection<Drawable> drawables = Arrays.asList(
                new Point(0, 1),
                new Point(5, 1),
                new Line(new Point(0, 0), new Point(5, 0))
        );
 
        final Drawing drawing = new Drawing(drawables, canvas);
        drawing.draw();
    }
 
}
Миниатюры
Как правильно составить иерархию классов\интерфейсов?  
1
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233
26.02.2015, 12:17  [ТС]
lemegeton, у меня пара вопросов:
Ваш Drawing это что-то типа моего DrawingRenderable, то есть это чертёж, который может отрисовываться. Но чертёж же не обязательно должен это уметь и где-то должен быть чертёж, который отвечает только за работу с элементами, которые опять же не Drawable.

И ещё: в классе SimpleTextOutputCanvas метод draw реализуется для каждого элемента. А если будут добавляться новые элементы, придётся добавлять и новую реализацию draw в никак не связанный с этим элементом SimpleTextOutputCanvas.

А в чём вы диаграмму составляли? Она составлена на основе кода?
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
26.02.2015, 15:28
Приведенный мной метод стар как само программирование. Называется "двойная диспетчеризация" или "множественная диспетчеризация".

Цитата Сообщение от x_Alex_x Посмотреть сообщение
Ваш Drawing это что-то типа моего DrawingRenderable, то есть это чертёж, который может отрисовываться. Но чертёж же не обязательно должен это уметь
Для простоты в примере оставленно минимум классов. Вы можете изменить зависимость, перенеся метод draw в другой удобный для вас класс. Например, выделить класс DrawingRenderer, которым и отрисовывать чертеж.

Цитата Сообщение от x_Alex_x Посмотреть сообщение
где-то должен быть чертёж, который отвечает только за работу с элементами, которые опять же не Drawable.
Поясните. Не вижу в постановке задачи ничего про чертеж, с не рисуемыми элементами.

Цитата Сообщение от x_Alex_x Посмотреть сообщение
И ещё: в классе SimpleTextOutputCanvas метод draw реализуется для каждого элемента. А если будут добавляться новые элементы, придётся добавлять и новую реализацию draw в никак не связанный с этим элементом SimpleTextOutputCanvas.
Совершенно верно. Канвас должен уметь отрисовывать каждый элемент. Придется добавлять метод в абстракцию и реализацию. От абстракции, кстати, можно отказаться, если у вас только один способ отрисовки. Будет проще.
Она нужна если вы собрались делать несколько реализаций выводов. Например, вывод на принтер, на экран и в файл.

Цитата Сообщение от x_Alex_x Посмотреть сообщение
А в чём вы диаграмму составляли? Она составлена на основе кода?
Диаграмма составлена при помощи триальной Intellij Idea на основе вышеприведенного кода.
1
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233
26.02.2015, 15:51  [ТС]
Цитата Сообщение от lemegeton Посмотреть сообщение
Поясните. Не вижу в постановке задачи ничего про чертеж, с не рисуемыми элементами.
Цитата Сообщение от x_Alex_x Посмотреть сообщение
класс Drawing(чертёж) позволяет работать с группой объектов DrawingElement(точка, отрезок...)
Это как раз оно. То есть изначально элементы, наследованные от класса DrawingElement отображаться не могут. Эта возможность появляется у наследников расширяющего его класса DRElement. То же самое с Drawing и DrawingRenderable.
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
27.02.2015, 18:14
Как-то непонятно, какая от этого польза. Усложняете же. Тогда нужно сделать наследника для каждого элемента геометрии, который будет имплементить Drawable.
1
20 / 20 / 3
Регистрация: 07.02.2014
Сообщений: 233
28.02.2015, 19:32  [ТС]
lemegeton, согласен, что усложняю, но я как-то сразу не додумался до этого.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.02.2015, 19:32
Помогаю со студенческими работами здесь

Как сделать иерархию классов?
А если быть точным. Как сделать иерархию классов так, чтобы к ним можно было обращаться как с общими. Сейчас поясню. Например, у нас...

Как лучше построить иерархию классов
Добрый день, пишу программу на курсовую, тема работы компьютер(строитель компьютера). И сомневаюсь, как построить иерархию классов. Сначала...

Как лучше сделать иерархию классов?
Здравствуйте! Мой вопрос заключается в том, что я хочу понять как лучше сделать иерархию классов: шаблонами или простым множественных...

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов и приложение, демонстрирующее работу с коллекцией объектов...

Подскажите как лучше всего реализовать иерархию классов
Есть класс Seller который cдает в аренду квартиры. Квартиры находятся в жилом округе, один Seller может управлять несколькими округами, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru