Можно ли использовать вложенные классы в качестве чистых наборов данных, как в других языках «Structs»? - PullRequest
2 голосов
/ 09 апреля 2020

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

Например, представьте, что мне нужен метод чтобы вернуть более одного значения, можно ли использовать этот очень простой вложенный класс для этой цели? Или это плохая практика?

В качестве примера представьте сценарий, в котором вы должны нарисовать фигуру, используя абсолютные координаты (слева, сверху, справа, снизу), и что для получения координат x и y щелкнули по экран, но вместо того, чтобы начать рисовать фигуру в этих координатах, нам нужно сместить их, чтобы нарисовать фигуру в центре этих координат, как показано в этом примере:


public class DrawSquare {

    private class Positions {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }


    //* These classes may not exist in java.
    //* They're here just to exemplify functionality.
    private Rectangle mSquare;
    private Paint mPaint;
    private Screen mScreen;

    private final int SIDE_LENGTH;

    public DrawSquare(int sideLength) {
        SIDE_LENGTH = sideLength;
        mSquare = new Rectangle();
    }

    //* Creates a square where the screen was clicked.
    public void createSquare() {
        Positions pos = processCoords(
                mScreen.getClickedX(),
                mScreen.getClickedY());

        //* Because the coords were processed, this rectangle
        //* will be created in the center of the clicked coords.
        mSquare.set(pos.left, pos.top, pos.right, pos.bottom);
        mPaint.draw(mSquare, mScreen);
    }


    //* Moves the square
    public void moveSquare() {
        Positions pos = processCoords(
                mScreen.getClickedX(),
                mScreen.getClickedY());

        //* Because the coords were processed, this rectangle
        //* will be moved to the center of the clicked coords.
        mPaint.animate(mSquare, mScreen)
                .moveTo(pos.left, pos.top, pos.right, pos.bottom)
                .setDuration(500)
                .start();
    }

    //* offset the coords to get a centered square
    private Positions processCoords(int x, int y) {
        Positions pos = new Positions();
        int halfLength = SIDE_LENGTH / 2;

        pos.left = x - halfLength;
        pos.top = y - halfLength;
        pos.right = x + halfLength;
        pos.bottom = y + halfLength;

        return pos;
    }

}

Это только что составлено типы объектов для иллюстрации сценария, который я изложил выше.

Это хороший вариант использования вложенного класса?

1 Ответ

1 голос
/ 09 апреля 2020

Такой подход почти идеален, с небольшим придиркой:

Используйте вложенный класс stati c вместо внутреннего класса:

public class DrawSquare {

    private static class Positions {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

Разница в том, что stati * Вложенный класс 1024 * не нуждается в ссылке на DrawSquare.


В Java 14 записи являются функцией предварительного просмотра.
Одним из применений для них является именно то, что вы делаете там :

public class DrawSquare {

    private record Positions(int left, int top, int right, int bottom) {}

Записи являются неизменяемыми, поэтому вам придется немного изменить свое создание:

private Positions processCoords(int x, int y) {
    int halfLength = SIDE_LENGTH / 2;

    int left = x - halfLength;
    int top = y - halfLength;
    int right = x + halfLength;
    int bottom = y + halfLength;

    return new Positions(left, top, right, bottom);
}

Запись автоматически создаст конструктор, средства доступа (.left() ... ) и перегрузку .equals(Object other), .hashCode() и .toString() для вас.

Но пока эта функция не входит в стандарт Java (без предварительного просмотра), ваш подход хорош.

...