Java中接受以下内容吗? 我知道它编译,但它是否在Java中被接受,或者我应该将代码更改为其他内容?
谢谢!
public class Line extends Shape {
public Line(int x1, int x2, int y1, int y2, Color myColor) {
super(x1, x2, y1, y2, myColor);
Point p1 = new Point(this.getX1(),this.getY1());
Point p2 = new Point(this.getX2(),this.getY2());
}
答案 0 :(得分:4)
如果要在构造函数外使用变量p1
和p2
,则必须将其声明为类级别变量,如此
Point p1;
Point p2;
public Line(int x1, int x2, int y1, int y2, Color myColor) {
super(x1, x2, y1, y2, myColor);
p1 = new Point(this.getX1(),this.getY1());
p2 = new Point(this.getX2(),this.getY2());
}
否则罚款。
答案 1 :(得分:3)
p1,p2 - 表示线点......问题是我想在某些对象的方法中使用这些点。
然后你必须在构造函数之外声明它们;如果你在构造函数中声明它们 ,那么它们就是局部变量。与任何函数中的局部变量一样,它们不在函数外的范围内。 ("功能" ="构造函数或方法")
你可以在构造函数中初始化它们,但你必须在外面声明它们:
public class Line extends Shape {
private Point p1; // You may or may not want the `private`, it...
private Point p2; // ...depends what you're going to do with them
public Line(int x1, int x2, int y1, int y2, Color myColor) {
super(x1, x2, y1, y2, myColor);
this.p1 = new Point(this.getX1(),this.getY1());
this.p2 = new Point(this.getX2(),this.getY2());
}
// ...
}
注意:访问上述实例字段可以使用或不使用前面的this.
来完成。 (例如,this.p1 = new ...
和p1 = new...
都有效。)我总是使用this.
,以便在查看代码时很容易辨别,我是否正在使用实例字段或局部变量;我的IDE还可以通过自动完成帮助我。不过,我想我可能是那里的少数人。
关于是否在构造函数外部或内部进行初始化的问题,让我们讨论在构造函数外部编写的初始化何时实际完成,这可能是不明显的:
class A {
int x;
int y;
public A(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
}
class B extends A {
private ImmutablePoint p = new ImmutablePoint(this.getX(), this.getY());
public B(int x, int y) {
super(x, y);
System.out.println("Hello from B");
}
public Point getP() {
return this.p;
}
}
看起来像初始化发生在构造函数被调用之前(无论如何)。那不是发生了什么。编译器为类B
生成的字节代码如下所示:
// Reconstituted version of the bytecode for our B above
class B extends A {
private ImmutablePoint p;
public B(int x, int y) {
super(x, y);
this.p = new ImmutablePoint(this.getX(), this.getY()); // <== Inserted
System.out.println("Hello from B");
}
public Point getP() {
return this.p;
}
}
注意它如何将插入初始化逻辑到构造函数中。
以下是在构造函数中编写初始化的一些原因,而不是声明的一部分:
如果你需要使用构造函数中唯一可用的信息(一个不会成为对象状态一部分的参数),你别无选择,你必须在构造函数中进行初始化。例如,除A
参数外,x
无法初始化其x
字段。
如果您需要在不同的构造函数中进行不同的初始化。同样,你别无选择,只能在构造函数中进行初始化,而不是使用声明。
(这是主观。)清晰度。由于初始化代码是在调用super
之后以及构造函数中的任何其他内容之前运行的,因此在源代码中将其写入有助于清晰。
有一个参数,用于在构造函数外部编写初始化,声明:
让我们在B
:
class B extends A {
private ImmutablePoint p = new ImmutablePoint(this.getX(), this.getY());
public B(int x, int y) {
super(x, y);
System.err.println("Hello from B");
}
public B(int x, int y, String msg) {
super(x, y);
System.out.println(msg);
}
public Point getP() {
return this.p;
}
}
现在我们有两个构造函数,它们使用一个参数或使用默认消息执行稍微不同的事情(System.err
与System.out
。)编译器生成的字节码实际上是这样做的:
// Reconstituted version of the bytecode for our B above
class B extends A {
private ImmutablePoint p;
public B(int x, int y) {
super(x, y);
this.p = new ImmutablePoint(this.getX(), this.getY()); // <== Inserted
System.err.println("Hello from B");
}
public B(int x, int y, String msg) {
super(x, y);
this.p = new ImmutablePoint(this.getX(), this.getY()); // <== Inserted
System.out.println(msg);
}
public Point getP() {
return this.p;
}
}
因此,在宣言中将初始化写入一个地方可能是有益的。
这是一种风格选择;另一种方法是使用公分母构造函数:
class B extends A {
private ImmutablePoint p;
private B(int x, int y) {
super(x, y);
this.p = new ImmutablePoint(this.getX(), this.getY());
}
public B(int x, int y) {
this(x, y);
System.err.println("Hello from B");
}
public B(int x, int y, String msg) {
this(x, y);
System.out.println(msg);
}
public Point getP() {
return this.p;
}
}
最后:Java还有初始化块,它们是在任何构造函数之外编写的初始化代码,但是以类似方法的方式:
class B extends A {
private ImmutablePoint p;
// Instance initializer block:
{
this.p = new ImmutablePoint(this.getX(), this.getY());
}
public B(int x, int y) {
super(x, y);
System.err.println("Hello from B");
}
public B(int x, int y, String msg) {
super(x, y);
System.out.println(msg);
}
public Point getP() {
return this.p;
}
}
初始化程序块中的逻辑可能有限。
所以你有各种各样的选择。除了 在构造函数(我之前的列表中为#1或#2)中进行初始化之外,它还是一种样式选择。