这两个构造函数之间的区别是什么。
Circle (Point2D center, double radius) {
this.center = center;
this.radius = radius;
}
Circle (Point2D center, double radius) {
this.center = new Point2D(center.getX(), center.getY());
this.radius = radius;
}
继承Point2D课程。这两个版本的构造函数都运行得很好。我感到困惑的是差异。
class Point2D {
double x;
double y;
Point2D () {
x = 0;
y = 0;
}
Point2D (double x, double y) {
this.x = x;
this.y = y;
}
void setX (double x) {
this.x = x;
}
void setY (double y) {
this.y = y;
}
void setXY (double x, double y) {
this.x = x;
this.y = y;
}
double getX () {
return x;
}
double getY () {
return y;
}
double distance (Point2D p) {
double x1 = p.getX();
double y1 = p.getY();
return Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2));
}
double distance (double x, double y) {
return Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2));
}
}
Circle类还有2个中心和半径。 center是Point2D类型,radius是double类型。我尝试编译并运行两个版本的构造函数。两者都运作良好。所以我很困惑哪一个会更好用,为什么,也有区别,因为在第一个我没有使用新操作来初始化中心对象。
答案 0 :(得分:4)
第二个构造函数使用原始Point2D
实例的defensive copy(由center
构造函数调用生成)以防止输入实例的进一步突变(更改),这可能非常令人困惑,产生错误
所以我很困惑哪一个会更好用,为什么
第二种方法更安全,因为您的Point2D
类是可变的。它使用更多的内存(以保持额外的防御性副本),但在真正复杂的项目中,这种设计实践的优点多于缺点。
如果你可以使Point2D
类immutable,那么可以使用第一个构造函数。
答案 1 :(得分:3)
第二个构造函数创建一个新的Point实例 - this.center = new Point2D(center.getX(), center.getY());
,而不是保持对传递给它的实例的引用。这意味着如果稍后修改了传递的center
,则更改不会影响Circle
实例。
第二个构造函数通常更安全,因为它有一个真正的私有Point
实例作为Circle
的中心,而第一个构造函数与构造函数的调用者共享center
您可以看到与此代码的区别:
Point2D point = new Point2D(10.0, 20.0);
Circle circle = new Circle (point, 4.0);
point.setX (5.0);
System.out.println(circle); // assuming you override toString to display the properties
// of the Circle
如果使用第一个构造函数,执行此代码后,您的圆将具有(5.0,20.0)的中心,而如果使用第二个构造函数,则圆的中心将为(10.0,20.0);
答案 2 :(得分:0)
Point2D
不是不可变的,即具有可在构造点之后更改的属性。
Circle
的第一个构造函数只使用Point2D
对象 - 现在调用者可以更改也会影响圆的点对象。
Circle
的第二个构造函数生成Point2D
对象的副本。如果圆圈保持点对象的私密性,则无法从外部更改。
答案 3 :(得分:0)
this.center = center
,您使用center
对象的参数。
this.center = new Point2D(center.getX(), center.getY())
,您使用参数Point2D
创建center
的新对象。