英文:
Is it okay to use nested classes as pure data sets, kind of like other languages 'Structs'?
问题
正如标题所述,是否可以使用一个非常简单的嵌套类作为数据容器,类似于其他编程语言中存在的结构体(Struct)?
例如,想象一下,如果我需要一个方法返回多个值,是否可以使用这个非常简单的嵌套类来实现这个目的?或者这是一种不好的做法?
举个例子,想象一个场景,你需要使用绝对坐标(左、上、右、下)来绘制一个形状,并且想要获取屏幕上点击位置的 x 和 y 坐标,但是不是从这些坐标开始绘制形状,而是需要偏移它们以在这些坐标的中心绘制形状,就像下面的示例所示:
public class DrawSquare {
private class Positions {
public int left;
public int top;
public int right;
public int bottom;
}
//* 这些类在 Java 中可能不存在。
//* 它们只是用来说明功能。
private Rectangle mSquare;
private Paint mPaint;
private Screen mScreen;
private final int SIDE_LENGTH;
public DrawSquare(int sideLength) {
SIDE_LENGTH = sideLength;
mSquare = new Rectangle();
}
//* 在屏幕点击的位置创建一个正方形。
public void createSquare() {
Positions pos = processCoords(
mScreen.getClickedX(),
mScreen.getClickedY());
//* 由于坐标已经被处理,这个矩形
//* 将在点击坐标的中心创建。
mSquare.set(pos.left, pos.top, pos.right, pos.bottom);
mPaint.draw(mSquare, mScreen);
}
//* 移动正方形
public void moveSquare() {
Positions pos = processCoords(
mScreen.getClickedX(),
mScreen.getClickedY());
//* 由于坐标已经被处理,这个矩形
//* 将被移动到点击坐标的中心。
mPaint.animate(mSquare, mScreen)
.moveTo(pos.left, pos.top, pos.right, pos.bottom)
.setDuration(500)
.start();
}
//* 将坐标偏移以获得一个居中的正方形
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;
}
}
上述示例中的对象类型只是虚构的,用于说明上述情景。
这是嵌套类的一个好的使用案例吗?
英文:
As the title says, is it okay to use a very trivial nested class just as a data holder, to act like a Struct existent in other programming languages?
For example, imagine that I need a method to return more than one value, is it okay to use this very simple nested class for this purpose? Or is it a bad practice?
As an example, imagine a scenario where you have to draw a shape using absolute coordinates (left, top, right, bottom) and what to retrieve the x and y coordinates clicked on a screen, but instead of starting to draw the shape at those coordinates, we need to offset them to draw the shape in the center of those coords, like this example demonstrate:
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;
}
}
Those are just made up object types to exemplify the scenario I stated above.
Is that a good use case of a nested class?
答案1
得分: 1
这种方法几乎是不错的,只有一个小问题:
使用静态嵌套类而不是内部类:
public class DrawSquare {
private static class Positions {
public int left;
public int top;
public int right;
public int bottom;
}
区别在于,静态嵌套类不需要对 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(不再是预览版)之前,您的方法是可以的。
英文:
That approach is almost fine, with a small nitpick:
Use a static nested class instead of an inner class:
public class DrawSquare {
private static class Positions {
public int left;
public int top;
public int right;
public int bottom;
}
The difference is that a static nested class does not need a reference to a DrawSquare.
In Java 14, records are a preview feature.
One of the uses for them are exactly what you are doing there:
public class DrawSquare {
private record Positions(int left, int top, int right, int bottom) {}
Records are immutable, so you would have to change your creation a bit:
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);
}
A record will automatically create a constructor, accessors (.left()
...) and overload .equals(Object other)
, .hashCode()
and .toString()
for you.
But until this feature is in standard Java (without preview), your approach is fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论