2014-12-07 100 views
1

我在理解繼承如何在Java中工作時遇到問題。我有3個相互延伸的類。第三課是我遇到問題的棘手問題。繼承和抽象如何與多個類一起工作? [java]

public abstract class Shape{ 
    //methods and variables 
    protected final static int X_MAX_SIZE = 800; 
    protected final static int Y_MAX_SIZE = 600; 
    private int xCord; 
    private int yCord; 

    public void setX(int newX){ 
     if(newX > 0 && newX < 800){ 
      this.xCord = newX; 
     } 
     else { 
      System.out.println("Invalid size."); 
      this.xCord = 0; 
     } 
    } 

    public int getX(){ 
     return xCord; 
    } 

    public void setY(int newY){ 
     if(newY > 0 && newY < 600){ 
      this.yCord = newY; 
     } 
     else{ 
      System.out.println("Invalid size."); 
      this.yCord = 0; 
     } 

    } 

    public int getY(){ 
     return yCord; 
    } 

    public Shape(){ 

    } 

    public Shape(int xCord, int yCord){ 

    } 

    abstract void display(); 
    abstract double area(); 

} 

public class Rectangle extends Shape { 
    // the inherited methods and calculations 
    int width, height; 

    public int getHeight(){ 
     return height; 
    }  
    public void setHeight(int newHeight){ 
     this.height = newHeight; 
    } 

    public int getWidth(){ 
     return width; 
    } 
    public void setWidth(int newWidth){ 
     this.width = newWidth; 
    } 

    public Rectangle(){ 

    } 

    public Rectangle(int x, int y, int height, int width){ 
     setX(x); 
     setY(y); 
     setHeight(height); 
     setWidth(width); 

    } 

    @Override 
    void display(){ 
     String toScreen = "Rectangle X: " + getX() + "\nRectangle Y: " + getY(); 
     String toScreenInfo = "\nRectangle height: " + getHeight() + "\nRectangle Width:getWidth(); 
     String toScreenArea = "\nRectangle area: " + area(); 
     System.out.println(toScreen + toScreenInfo + toScreenArea); 
    } 

    @Override 
    double area(){ 
     return (width * height); 
    } 

    } 

} 

public class Square extends Rectangle { 
    // more methods, but no new variables. & calculations 


    public Square(int x, int y, int height, int width){ 
     setX(x); 
     setY(y); 
     setHeight(height); 
     setWidth(width); 
    } 

    public Square(){ 
     super();   
    } 

    @Override 
    public void setHeight(int height){ 
     if(height != getWidth()){ 
      height = getWidth(); 
     } 
    } 
    @Override 
    public void setWidth(int width){ 
     if(width != getHeight()){ 
      width = getHeight(); 
     } 
    } 

    @Override 
    double area(){ 
     return (width * height); 
    } 

    @Override 
    void display(){ 
     String toScreen = "Square area is " + area(); 
    } 
    } 
} 

類廣場我甚至有麻煩,甚至在主要調用。 所以我在這裏的目標是改變Square類的值,以確保'高度'和'寬度'彼此相等以形成一個正方形。我的約束無法在get/set和構造函數中創建任何新變量。

+0

嗯,你認爲我們是介意讀者嗎?沒有任何人提供足夠的信息來幫助你。 – ajb 2014-12-07 04:31:24

+0

這是所有的代碼是什麼?還是有更多的代碼與你一起工作可能會導致你遇到的問題?而且,究竟是什麼問題呢? – 2014-12-07 04:32:23

+0

你需要發佈一個實際產生你聲稱收到的結果的例子。 – csmckelvey 2014-12-07 04:33:47

回答

0

繼承應該總是表示對象之間的「是」關係,在您的示例中也是如此。

正方形是一個矩形。 矩形是一個形狀。

如果對象自然不具有「是」的關係,那麼繼承可能是組織它們的糟糕方式(基於接口的類型層次結構可能會更好)。

正方形將具有矩形的成員(方法和字段)。 矩形將具有形狀的成員(方法和字段)。子類可以重寫父方法以提供更具體的行爲。

如果您遇到更爲特殊的問題,您需要提供更多幫助。

+0

正方形是數學*中的矩形*。編程時,正方形不是*長方形。這是用來說明裏斯科替代原則的典型例子。 – 2014-12-07 04:52:51

+0

編程時,如果沒有可以獨立更改高度或寬度的setter方法,則該方形是一個矩形。 – ajb 2014-12-07 05:33:10

+0

@EricStein:一個正方形在編程中可能是也可能不是一個矩形。它取決於建模中抽象的正方形和矩形的精確語義。爲了介紹繼承,我打算簡單地說明一個「是」的關係。這並不合適。 – scottb 2014-12-07 06:22:23

0

如果您在類形狀中有任何抽象方法,則可以在Square類或Rectangle類中覆蓋它的每個部分。 如果您也想創建Rectangle的對象,那麼您應該只覆蓋Rectangle中的所有抽象方法。

並且這裏的繼承是多級不是多級的

0

你想要什麼都做不到。事實上,這是用來證明Liskov替代原則的典型例子。 Square不能擴展Rectangle,而Rectangle不能擴展Square。即:

class Square extends Rectangle { 
    ... 
} 

public void someMethod(final Rectangle r) { 
    r.setHeight(300); 
    r.setWidth(500); 
} 

final Square square = new Square(200, 200); 
someMethod(square); 
display(square); // UHOH!! 
+1

那麼,如果Square是不可變的,那麼'Square'可以擴展'Rectangle'。或可能在其他一些受限制的條件下。無論如何,這個*當然可以做到,即使它不應該,但我認爲教官仍然在用這樣的例子來教授繼承機制。所以如果有人在這個層面上並試圖弄清楚基本知識,那麼向他們投擲LSP可能不是最有用的答案。 – ajb 2014-12-07 05:30:57

+0

@ajb - 如果基本知識儘快明確,我認爲損失最小。只是我的觀點。 – Ouney 2014-12-07 05:41:35

+0

@ajb我有點兒希望老師試圖指出LSP是具體擴展的陷阱。不管教練的意圖如何,沒有好的方法來完成OP想要完成的任務。 – 2014-12-08 00:25:22

-2

的問題是,在Rectangle,你有方法setHeightsetWidth,即設置實例變量heightwidth。在Square中,您不需要聲明新的實例變量。因此,要設置高度和寬度,您需要使用Rectangle中聲明的setHeightsetWidth方法。

但是,你不這樣做的SquareSquare類覆蓋了setHeightsetWidth方法。對於那些設置實例變量,他們需要調用Rectangle中定義的setHeightsetWidth方法。要做到這一點的方法是:

super.setHeight(h); // calls the Rectangle method, which sets the variable 
super.setWidth(w);  

既然你不使用時,setHeightsetWidth方法Square只是稱呼對方,而不是那些在Rectangle,其結果是,heightwidth變量永遠不會被設置。

+0

有人可以解釋downvote?我有什麼不對嗎?或者有人不高興,我沒有得到「你不能這樣做」LSP的潮流?無論如何,提問者需要了解'super.method'語法。 – ajb 2014-12-07 05:54:41

+0

基於此,這是否意味着,只要教師分配一個遞歸分配並不適合遞歸(像其中大多數),我們是否應該減少每個試圖幫助學生的人? – ajb 2014-12-07 05:58:48