簡體   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