简体   繁体   English

创建超类和子类 Java question

[英]Creating Superclasses and Subclasses Java quesiton

i started learning Java in university and we have an assignment that requires us to use a Superclass for Shape and Subclass that extend the shape.我在大学开始学习 Java,我们有一个任务要求我们使用超类的形状和扩展形状的子类。

This is the full questions:这是完整的问题:

Create a super class “Shape” from which you derive two subclasses “Square” and “Rectangle” with functions to calculate the square area and the rectangle area.创建一个超级 class “Shape”,从中派生两个子类“Square”和“Rectangle”,它们具有计算正方形面积和矩形面积的函数。 In addition, to the function “toString” to display the square and rectangle info.此外,对 function “toString” 显示正方形和矩形信息。 Derive another sub class “Cube” from square with a function to calculate its area and a function “toString” to display the cube info."从正方形派生另一个子 class “立方体”,用 function 计算其面积,用 function “toString” 显示立方体信息。

What we need to do is calculate the shapes using the classes.我们需要做的是使用类计算形状。 Where should I start or move forward to solve the assignment?我应该从哪里开始或继续解决任务?

This is where I think I should start, but need some guidance这是我认为我应该开始的地方,但需要一些指导

public class Shapes {
  class Shape {

  }

  class Rectangle extends Shape {

  }

  class Square extends Shape {

  }
}

First, Shape class should be abstract , since you won't create any specific object of this class and you'll only use it as a "canvas".首先, Shape class 应该是abstract ,因为您不会创建此 class 的任何特定 object 并且您只会将其用作“画布”。 This class has to have an abstract method, let's call it getArea() , that you'll have to override in your child classes to accomodate to the specified requirements for each kind of shape.这个 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. 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.

According to the definition you have post, the Cube class would be a composition of Square (a cube is composed by squares, but it's not a square), so I'd extend it from Shape and define it as a List or an array of 6 Square , so the getArea() of Cube would be the summatory of every Square area in it.根据您发布的定义, Cube class 将是Square的组合(立方体由正方形组成,但它不是正方形),所以我将从Shape扩展它并将其定义为List或数组6 Square ,因此CubegetArea()将是其中每个Square区域的总和。

Putting aside the quality of the question:抛开问题的质量:

You have a Shape class that will contain a method calculateSomething() .你有一个 Shape class ,它将包含一个方法calculateSomething() Shape does not define a specific shape so most likely you can return a -1 or 0? Shape 没有定义特定的形状,所以很可能您可以返回 -1 或 0?

Now, we can determine that the method of the Shape class does not provide us with any real value/info.现在,我们可以确定 Shape class 的方法没有为我们提供任何实际值/信息。 Even if you create a Shape shape = new Shape() object and call its method, it does not help us at all.即使你创建一个Shape shape = new Shape() object 并调用它的方法,它对我们一点帮助也没有。

Instead it provides us with a method that each subclass has to override in order to get the intended results.相反,它为我们提供了一个方法,每个子类都必须重写该方法才能获得预期的结果。

What does that mean and how it works?这是什么意思以及它是如何工作的?

For you to not always have to do Rectangle rect = new Rectangle() for every single class and object, the Rectangle becomes a subclass of the Shape class.为了让您不必总是为每个 class 和 object 执行Rectangle rect = new Rectangle() ,矩形成为形状 class 的子类。

This enables you to later do Shape rect = new Rectangle() .这使您可以稍后执行Shape rect = new Rectangle() The big benefit of this is that you create an abstraction mechanism, meaning that you have a lot of shapes, either rectangles or triangles etc, but they all are Shape objects in the end.这样做的最大好处是您创建了一个抽象机制,这意味着您有很多形状,无论是矩形还是三角形等,但最终它们都是 Shape 对象。

So later you can just do:所以以后你可以这样做:

Shape rect = new Rectangle();
Shape triangle = new Triangle();
rect.calculate();
triangle.calculate();

Instead of the more meticulous:而不是更细致:

Rectangle rect = new Rectangle();
Triangle triangle = new Triangle();
rect.calculate();
triangle.calculate();

The former can further be utilised by:前者可以进一步用于:

// 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);

As you can see for yourself, it is easier to handle and iterate over a list with all the elements being of type/class Shape.正如您自己所看到的,处理和迭代所有元素都是类型/类 Shape 的列表更容易。

// Basic example
for (Shape shape : shapes)
    shape.calculateSomething();

Imagine if you had a hundred different shapes except Rectangle and Triangle.想象一下,如果你有一百种不同的形状,除了矩形和三角形。 The latter method, without using inheritance, would quickly come to consume your project in an ever ending trial of maintenance and code changing.后一种方法在不使用 inheritance 的情况下,很快就会在不断结束的维护和代码更改试验中消耗您的项目。

By utilising inheritance otherwise, you can increase your Shape classes as much in quantity as you want and the same methods that used to work for a Shape, would still work for all the future new objects.否则,通过使用 inheritance,您可以根据需要增加 Shape 类的数量,并且用于 Shape 的相同方法仍然适用于所有未来的新对象。

How does it work in practise?它在实践中是如何工作的? How do i create a subclass?如何创建子类?

As you already know you can link your classes through the extend keyword.如您所知,您可以通过extend关键字链接您的类。 But that is only the start.但这仅仅是开始。

To be able to utilize the inheritance, you will have to overwrite the method of your choosing, in the child class.为了能够使用 inheritance,您必须在子 class 中覆盖您选择的方法。

Take for instance the previous example:以前面的例子为例:

Shape rect = new Rectangle();
rect.calculate();

But that raises the question, how can you get the correct value of calculate() method, when Shape class has a -1 or 0 returning from it and rect variable is now of type Shape ?但这提出了一个问题,当Shape class 从它返回 -1 或 0 并且rect变量现在是Shape类型时,如何获得calculate()方法的正确值?

Easily, you can override a method of the parent class through the @Override tag and by implementing the same method again on the child class but with different calculations.很容易,您可以通过@Override标记覆盖父 class 的方法,并在子 class 上再次实施相同的方法,但计算方式不同。 Example:例子:

class Shape {
    
    public void calculate() { return 0; }
}

class Rectangle extends Shape {
     
    @Override
    public void calculate() { return 2; }
}

Note that the name, variables etc of the method must be identical.请注意,方法的名称、变量等必须相同。

Now in the case of:现在在以下情况下:

Shape rect = new Rectangle();
rect.calculate();

the calculate() method will return the number 2 . calculate()方法将返回数字2 This happens because even though the rect object is of type Shape , it is also a Rectangle .发生这种情况是因为即使rect object 是Shape类型,它也是一个Rectangle Every Rectangle is a Shape.每个矩形都是一个形状。 So when you try to call the desired method, the program knows to choose the overrided method of the Rectangle class, because in essence it is a Rectangle, covered by the abstraction Shape.因此,当您尝试调用所需的方法时,程序知道选择 Rectangle class 的覆盖方法,因为它本质上是一个 Rectangle,被抽象 Shape 覆盖。

This works for any number of Shape subclasses, each with their own unique implementation of the method.这适用于任意数量的 Shape 子类,每个子类都有自己独特的方法实现。

Also note that a Rectangle subclass can have its own private fields that are used in the other methods:另请注意, 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; 
    }
}

So to answer your question, you just override the methods you want for each class as you desire.因此,要回答您的问题,您只需根据需要覆盖每个 class 所需的方法。 If a method is not overriden, then the original of the Shape parent class is run.如果未覆盖方法,则运行Shape父级 class 的原始方法。

I hope this shined a little bit of light in your confusion towards abstraction and inheritance.我希望这能让您对抽象和 inheritance 感到困惑。

PS: I know that you might be confused, but there are hundreds of answers and forums out there explaining this exact thing and that is how we all learned it. PS:我知道您可能会感到困惑,但是那里有数百个答案和论坛来解释这个确切的事情,而这就是我们所有人的学习方式。 It needs time unfortunately but you will have a deeper understanding if you look at something yourself.不幸的是,这需要时间,但如果你自己看一些东西,你就会有更深入的理解。 I'm sure you have taken a taste of what is defined as 'wrong' or 'bad' to ask in here and that you will be more susceptible into studying it yourself in the future, considering there is material needed.我敢肯定,您已经尝到了在这里提出的“错误”或“不好”的定义,并且考虑到需要材料,您将来会更容易自己研究它。 I just tried to reach out to you because i have been in your place and believed i could make a difference with my approach.我只是想与您联系,因为我一直在您的位置上,并相信我可以通过我的方法有所作为。

If you have anything else to add or something to correct, it is always welcome in the comments section.如果您还有其他要添加或要更正的内容,请随时在评论部分中进行。

Edit: As mentioned by the other guy that answered, the Shape class can and should be an abstract one.编辑:正如另一个回答的人所提到的,形状 class 可以而且应该是一个抽象的形状。 I just assumed you wanted it to be a normal one.我只是假设你希望它是一个正常的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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