繁体   English   中英

创建超类和子类 Java question

[英]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 ,因此CubegetArea()将是其中每个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM