Java中为Rect类添加宽高合法性控制的实现方法
问题描述
我创建了一个仅包含矩形属性的Rect类,希望实现以下逻辑:width和length必须为大于0的整数,若传入负数则取其绝对值。已有多年未使用Java,相关经验有限,不清楚应在何处编写对应代码,附上当前Rect类代码:
public class Rect { int x; int y; int width; int length; public int getPerimeter() { return (2 * width) + (2 * length); } public int getArea() { return width * length; } public void move(int x, int y) { this.x = x; this.y = y; } public void changeSize(int n) { this.width = n; this.length = n; } public void print(int area, int perimeter) { System.out.printf("X: %d\n", this.x); System.out.printf("Y: %d\n", this.y); System.out.printf("Length: %d\n", this.width); System.out.printf("Width: %d\n", this.length); System.out.printf("Area: %d\n", area); System.out.printf("Perimeter: %d", perimeter); } public static void main(String[] args) { Rect r1 = new Rect(); r1.length = 1; r1.width = 2; r1.x = 3; r1.y = 4; //test here int area = r1.getArea(); int perimeter = r1.getPerimeter(); r1.print(area, perimeter); } }
解决方案
要实现width和length的合法性校验,核心是封装成员变量,通过Getter/Setter方法控制属性赋值逻辑,避免外部直接操作成员变量。具体实现步骤如下:
1. 私有化成员变量
将所有属性设为private,禁止外部直接修改:
private int x; private int y; private int width; private int length;
2. 编写带校验逻辑的Setter方法
为width和length编写Setter方法,在方法内处理负数取绝对值,同时确保值大于0(若传入0则默认设为1,可根据需求调整):
public void setWidth(int width) { this.width = Math.abs(width); // 保证值大于0,避免传入0的情况 if (this.width == 0) { this.width = 1; } } public void setLength(int length) { this.length = Math.abs(length); if (this.length == 0) { this.length = 1; } }
同时为x、y编写普通Setter方法(无需校验逻辑),并为所有属性添加Getter方法:
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; } public int getWidth() { return width; } public int getLength() { return length; }
3. 修改现有方法与初始化逻辑
- 调整
changeSize方法,使用Setter而非直接赋值:
public void changeSize(int n) { setWidth(n); setLength(n); }
- 修正
print方法的输出错误(原代码将width和length的输出搞反了):
public void print(int area, int perimeter) { System.out.printf("X: %d\n", this.x); System.out.printf("Y: %d\n", this.y); System.out.printf("Length: %d\n", this.length); System.out.printf("Width: %d\n", this.width); System.out.printf("Area: %d\n", area); System.out.printf("Perimeter: %d", perimeter); }
- 修改main方法的初始化代码,使用Setter设置属性:
public static void main(String[] args) { Rect r1 = new Rect(); r1.setLength(1); r1.setWidth(2); r1.setX(3); r1.setY(4); // 测试负数输入 r1.setWidth(-5); r1.setLength(-3); int area = r1.getArea(); int perimeter = r1.getPerimeter(); r1.print(area, perimeter); }
4. 可选:添加带参构造方法
添加构造方法,在创建对象时直接完成属性的校验初始化:
public Rect(int x, int y, int width, int length) { setX(x); setY(y); setWidth(width); setLength(length); }
使用示例:
Rect r1 = new Rect(3, 4, 2, 1);
完整修改后的代码
public class Rect { private int x; private int y; private int width; private int length; // 无参构造 public Rect() {} // 带参构造 public Rect(int x, int y, int width, int length) { setX(x); setY(y); setWidth(width); setLength(length); } public int getPerimeter() { return (2 * width) + (2 * length); } public int getArea() { return width * length; } public void move(int x, int y) { setX(x); setY(y); } public void changeSize(int n) { setWidth(n); setLength(n); } public void print(int area, int perimeter) { System.out.printf("X: %d\n", this.x); System.out.printf("Y: %d\n", this.y); System.out.printf("Length: %d\n", this.length); System.out.printf("Width: %d\n", this.width); System.out.printf("Area: %d\n", area); System.out.printf("Perimeter: %d", perimeter); } // Getter和Setter方法 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; } public int getWidth() { return width; } public void setWidth(int width) { this.width = Math.abs(width); if (this.width == 0) { this.width = 1; } } public int getLength() { return length; } public void setLength(int length) { this.length = Math.abs(length); if (this.length == 0) { this.length = 1; } } public static void main(String[] args) { Rect r1 = new Rect(); r1.setLength(1); r1.setWidth(2); r1.setX(3); r1.setY(4); // 测试负数输入 r1.setWidth(-5); r1.setLength(-3); int area = r1.getArea(); int perimeter = r1.getPerimeter(); r1.print(area, perimeter); } }
内容的提问来源于stack exchange,提问作者msalaz03
相关产品推荐
相关产品推荐

