因此,我正在尝试为我的其中一篇教程编写一些代码。输入和预期输出是这样的:
> Square s = new Square(5);
> s.toString();
< Square with area 25.00 and perimeter 20.00
以下是我的代码:
abstract class Shape {
protected String shapeName;
public abstract double getArea();
public abstract double getPerimeter();
@Override
public String toString() {
return shapeName + " with area " + String.format("%.2f", getArea()) +
" and perimeter " + String.format("%.2f", getPerimeter());
}
}
class Rectangle extends Shape {
protected double width;
protected double height;
public Rectangle(double width) {
this.shapeName = "Rectangle";
this.width = this.height = width;
}
public Rectangle(double width, double height) {
this.shapeName = "Rectangle";
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2 * (width + height);
}
}
class Square extends Rectangle {
public Square(double side) {
this.shapeName = "Square";
this.width = this.height = side;
}
}
问题是当我尝试编译它时,发生此错误:
error: no suitable constructor found for Rectangle(no arguments)
public Square(double side) {
^
constructor Rectangle.Rectangle(double) is not applicable
(actual and formal argument lists differ in length)
constructor Rectangle.Rectangle(double,double) is not applicable
(actual and formal argument lists differ in length)
在这种情况下,我不确定继承如何工作。如何修改代码,使输入返回正确的输出?我认为错误仅在于Square类,否则代码将编译。
谢谢。
答案 0 :(得分:3)
从设计角度来说,我觉得矩形的构造函数Rectance(double width)是不自然的,因此将其删除。 Square的构造函数应如下所示:
public Square(double side) {
super(side,side); // width == height
this.shapeName = "Square";
}
要进一步阐明继承,您还可以将this.shapeName= "Rectangle";
行替换为this.shapeName= getClass().getSimpleName();
,并从this.shapeName = "Square";
的构造函数中删除Square
。
答案 1 :(得分:1)
只是为了澄清错误消息:
error: no suitable constructor found for Rectangle(no arguments) public Square(double side) { ^ constructor Rectangle.Rectangle(double) is not applicable (actual and formal argument lists differ in length) constructor Rectangle.Rectangle(double,double) is not applicable (actual and formal argument lists differ in length)
任何子类的构造函数(例如Square
)都必须调用其父类(Rectangle
)的构造函数,因为还必须构造父部分。
如果程序员没有提供此构造函数,即未显式调用(例如在问题代码中),则编译器将自动插入对父级的无参数构造函数的调用(例如在public Square(...) { super(); ... }
中)
在这个问题上,由于父(Rectangle
)没有这样的构造函数,编译器会发送错误。因此,必须在代码中显式调用父类的构造函数,例如in(如已回答):
public Square(double side) {
super(side,side); // width == height
...
答案 2 :(得分:0)
您必须在继承类中显式调用super
构造函数。
而且,如果您想将@runec的答案考虑在内(是的,我赞成,因为它很不错),您可能想从{{1} },并使Rectangle
处理具有4个相等边的矩形。
Square
这里的public class Rectangle extends Shape {
protected double width;
protected double height;
public Rectangle(double width, double height) {
this.shapeName = "Rectangle";
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2 * (width + height);
}
}
仅包含一个Square
参数:
double
此答案仅用于显示完整的代码,完整的想法来自@runec。