@jspie

Как правильно организовать иерархию классов и методов квадрата?

Нужно разработать класс Квадрат, линия и точка. Квадрат должен иметь методы: изменить размер, повернуть. Сделать это нужно без графического интерфейса. Нужно просто выводить координаты или коэффициент изменения. Я не знаю как более просто можно это все организовать. Получается пока что как то так:
package com.company;

import java.util.ArrayList;
import java.util.List;

class Rect{
    private int size = 0;
    private int rot = 0;

    List<Line> lines;

    public Rect(){}

    public Rect(int _size){
        this.size = _size;

        lines = new ArrayList<Line>();

        Line lines1 = new Line(0,0, 0, _size);
        lines.add(lines1);

        Line lines2 = new Line(0, _size, _size, _size);
        lines.add(lines2);

        Line lines3 = new Line(_size , _size, _size, _size);
        lines.add(lines3);

        Line lines4 = new Line(_size,0, 0,0);
        lines.add(lines4);
    }

    public void setSize(int _size) {
        this.size = _size;

        for(int i = 0; i < 4; i++)
        {
            System.out.println(lines.get(i).getLine());
        }
    }

    public void Rotation(int u){

    }

    public void Show()
    {

    }
}

class Dot {
    private int x = 0;
    private int y = 0;

    public Dot(int _x, int _y) {
        this.x = _x;
        this.y = _y;
    }

    public int getX() { return x; }

    public void setX(int x) { this.x = x; }

    public int getY() { return y; }

    public void setY(int Y) { this.y = y; }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "{x: " + x
                + ", y: " + y +
        "}";
    }
}

class Line {
    Dot dot1;
    Dot dot2;

    List<Dot> dots;

    public Line(){

    }

    public Line(int x1, int y1, int x2, int y2) {
        dot1 = new Dot(x1, y1);
        dot2 = new Dot(x2, y2);

        dots = new ArrayList<Dot>();

        dots.add(dot1);
        dots.add(dot2);
    }

    public void setLine(int x1, int y1, int x2, int y2) {
        dots = new ArrayList<Dot>();

        dot1.setX(x1);
        dot1.setY(y1);

        dot2.setX(x2);
        dot2.setY(y2);

        dots.add(dot1);
        dots.add(dot2);
    }

    public List<Dot> getLine()
    {
        return dots;
    }
}
public class Main {

    public static void main(String[] args) {
        Rect rect = new Rect(10);
        rect.setSize(12);

    }
}

Но столкнулся с проблемами когда не могу изменить текущие координаты и т.д. Скорее всего я не правильно организовал структуру. Помогите новичку
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
  • @erlioniel
    Java Developer
    Самый простой (в лоб) подход будет сделать одну структуру. Я опущу все геттеры, сеттеры и прочие Java-штуки, просто чтобы оставить код максимально простым. В целом их использовать более чем стоит.

    class Rect {
        public int aX;
        public int aY;
        public int bX;
        public int bY;
        public int cX;
        public int cY;
        public int dY;
        public int dX;
    }


    И дальше воротить от этой структуры данных уже нужные себе вещи. Опять же я опущу все лишнее и оставлю только сам метод (например умножения).

    public Rect multiply(Rect source, float amount) {
            Rect result = new Rect();
            result.aX = source.aX * amount;
            result.aY = source.aY * amount;
            result.bX = source.bX * amount;
            result.bY = source.bY * amount;
            result.cX = source.cX * amount;
            result.cY = source.cY * amount;
            result.dX = source.dX * amount;
            result.dY = source.dY * amount;
            return result;
        }


    Если хочется более "объектно-ориентированной" структуры то нужно для начала понять какие объекты в ней будут реально обладать поведением. Ну то есть например в классических примерах с кошками-собаками-животными почему-то никто не стремится делать в кошке объект Язык, который будет отвечать за конкретный "Мяу". Тут так же, если точка (как объект) не несет сама по себе никакого функционала совсем не факт что она нужна. Соответственно первое что тут просится это собрать квадрат (или если уж на то пошло - многоугольник) как просто коллекцию ребер. Тогда получится что-то такое:

    class Edge {
        public float aX;
        public float aY;
        public float bX;
        public float bY;
    }
    
    class Poly extends ArrayList<Edge> {
        public Poly multiply(Poly source, float amount) {
            Poly result = new Poly();
            for (Edge edge : source) {
                Edge newEdge = new Edge();
                newEdge.aX = edge.aX * amount;
                newEdge.aY = edge.aY * amount;
                newEdge.bX = edge.bX * amount;
                newEdge.bY = edge.bY * amount;
                result.add(newEdge);
            }
            return result;
        }
    }


    Проблема такого подхода, как я описал выше, что точка сама по себе не существует и не может содержать логики. Например если тебе нужно будет подвигать точку на экране то реализовать эту логику будет непросто в данном случае, потому что придется искать все ребра которые задеты этим. Решить же это можно если ввести класс точек, что превратит наш код в примерно вот такой:

    class Dot {
        public float x;
        public float y;
    }
    
    class Edge {
        public Dot a;
        public Dot b;
    }
    
    class Poly extends ArrayList<Dot> {
        public List<Edge> edges = new ArrayList<>();
    
        public Poly multiply(Poly source, float amount) {
            Poly result = new Poly();
            // Map just to remember old dots bindings
            Map<Dot, Dot> newDots = new HashMap<>();
            for (Dot dot : source) {
                Dot newDot = new Dot();
                newDot.x = dot.x * amount;
                newDot.y = dot.y * amount;
                result.add(dot);
                newDots.put(dot, newDot);
            }
            
            for (Edge edge : edges) {
                Edge newEdge = new Edge();
                newEdge.a = newDots.get(edge.a);
                newEdge.b = newDots.get(edge.b);
                result.edges.add(newEdge);
            }
            
            return result;
        }
    }


    Как видно, добавление новой сущности сделало весь код сложнее, а клонирование объекта куда более комплексным. Хотя теперь возможно изменять точку и не думать о том что какие-то ребра будут забыты.

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

    Этот код дан исключетельно как ответ на вопрос и на подумать, не стоит так писать в реальных приложениях. Надеюсь ответ будет полезен ;)
    Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы