[英]Creating Superclasses and Subclasses Java quesiton
我在大学开始学习 Java,我们有一个任务要求我们使用超类的形状和扩展形状的子类。
这是完整的问题:
创建一个超级 class “Shape”,从中派生两个子类“Square”和“Rectangle”,它们具有计算正方形面积和矩形面积的函数。 此外,对 function “toString” 显示正方形和矩形信息。 从正方形派生另一个子 class “立方体”,用 function 计算其面积,用 function “toString” 显示立方体信息。
我们需要做的是使用类计算形状。 我应该从哪里开始或继续解决任务?
这是我认为我应该开始的地方,但需要一些指导
public class Shapes {
class Shape {
}
class Rectangle extends Shape {
}
class Square extends Shape {
}
}
首先, Shape
class 应该是abstract
,因为您不会创建此 class 的任何特定 object 并且您只会将其用作“画布”。 这个 class 必须有一个抽象方法,我们称之为getArea()
,你必须在你的子类中重写它以适应每种形状的指定要求。
The toString()
method belongs to Object
class, since every class in Java extends from Object
, you don't have to define anything, just override this method to return the desired String
in every child class.
根据您发布的定义, Cube
class 将是Square
的组合(立方体由正方形组成,但它不是正方形),所以我将从Shape
扩展它并将其定义为List
或数组6 Square
,因此Cube
的getArea()
将是其中每个Square
区域的总和。
抛开问题的质量:
你有一个 Shape class ,它将包含一个方法calculateSomething()
。 Shape 没有定义特定的形状,所以很可能您可以返回 -1 或 0?
现在,我们可以确定 Shape class 的方法没有为我们提供任何实际值/信息。 即使你创建一个Shape shape = new Shape()
object 并调用它的方法,它对我们一点帮助也没有。
相反,它为我们提供了一个方法,每个子类都必须重写该方法才能获得预期的结果。
这是什么意思以及它是如何工作的?
为了让您不必总是为每个 class 和 object 执行Rectangle rect = new Rectangle()
,矩形成为形状 class 的子类。
这使您可以稍后执行Shape rect = new Rectangle()
。 这样做的最大好处是您创建了一个抽象机制,这意味着您有很多形状,无论是矩形还是三角形等,但最终它们都是 Shape 对象。
所以以后你可以这样做:
Shape rect = new Rectangle();
Shape triangle = new Triangle();
rect.calculate();
triangle.calculate();
而不是更细致:
Rectangle rect = new Rectangle();
Triangle triangle = new Triangle();
rect.calculate();
triangle.calculate();
前者可以进一步用于:
// Putting all the objects in a list
List<Shape> shapes = new ArrayList<>();
// Create objects and add them
Shape rect = new Rectangle();
Shape triangle = new Triangle();
shapes.add(rect);
shapes.add(triangle);
正如您自己所看到的,处理和迭代所有元素都是类型/类 Shape 的列表更容易。
// Basic example
for (Shape shape : shapes)
shape.calculateSomething();
想象一下,如果你有一百种不同的形状,除了矩形和三角形。 后一种方法在不使用 inheritance 的情况下,很快就会在不断结束的维护和代码更改试验中消耗您的项目。
否则,通过使用 inheritance,您可以根据需要增加 Shape 类的数量,并且用于 Shape 的相同方法仍然适用于所有未来的新对象。
它在实践中是如何工作的? 如何创建子类?
如您所知,您可以通过extend
关键字链接您的类。 但这仅仅是开始。
为了能够使用 inheritance,您必须在子 class 中覆盖您选择的方法。
以前面的例子为例:
Shape rect = new Rectangle();
rect.calculate();
但这提出了一个问题,当Shape
class 从它返回 -1 或 0 并且rect
变量现在是Shape
类型时,如何获得calculate()
方法的正确值?
很容易,您可以通过@Override
标记覆盖父 class 的方法,并在子 class 上再次实施相同的方法,但计算方式不同。 例子:
class Shape {
public void calculate() { return 0; }
}
class Rectangle extends Shape {
@Override
public void calculate() { return 2; }
}
请注意,方法的名称、变量等必须相同。
现在在以下情况下:
Shape rect = new Rectangle();
rect.calculate();
calculate()
方法将返回数字2 。 发生这种情况是因为即使rect
object 是Shape
类型,它也是一个Rectangle
。 每个矩形都是一个形状。 因此,当您尝试调用所需的方法时,程序知道选择 Rectangle class 的覆盖方法,因为它本质上是一个 Rectangle,被抽象 Shape 覆盖。
这适用于任意数量的 Shape 子类,每个子类都有自己独特的方法实现。
另请注意, Rectangle 子类可以有自己的私有字段,用于其他方法:
class Rectangle extends Shape {
private int height;
private int width;
// constructor
public Rectangle(int h, int w) {
this.height = h;
this.width = w;
}
@Override
public void calculate() {
return this.w * this.h;
}
}
因此,要回答您的问题,您只需根据需要覆盖每个 class 所需的方法。 如果未覆盖方法,则运行Shape
父级 class 的原始方法。
我希望这能让您对抽象和 inheritance 感到困惑。
PS:我知道您可能会感到困惑,但是那里有数百个答案和论坛来解释这个确切的事情,而这就是我们所有人的学习方式。 不幸的是,这需要时间,但如果你自己看一些东西,你就会有更深入的理解。 我敢肯定,您已经尝到了在这里提出的“错误”或“不好”的定义,并且考虑到需要材料,您将来会更容易自己研究它。 我只是想与您联系,因为我一直在您的位置上,并相信我可以通过我的方法有所作为。
如果您还有其他要添加或要更正的内容,请随时在评论部分中进行。
编辑:正如另一个回答的人所提到的,形状 class 可以而且应该是一个抽象的形状。 我只是假设你希望它是一个正常的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.