[英]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.