2015-07-11 298 views
1

首先,我只是把我的示例代碼。有一個方法接受不同的對象作爲參數

public class Shape { 

    public String colour; 

    public Shape(String colour) { 
     this.colour = colour; 
    } 

} 

public class Car { 

    public String colour; 

    public Car (String colour) { 
     this.colour = colour; 
    } 

} 

public class Colour { 

    public static String getColour(Object item) { 
     return item.**colour**; 
    } 

} 

我已閱讀了與此相關的其他問題,但我似乎無法理解。我發現他們的原始代碼對於我來說太複雜了。所以我試圖儘可能簡化代碼。無論如何,我希望getColour接受Shape和Car對象。如果我像我在我的例子中那樣使用Object,粗體的「顏色」被認爲是錯誤的。我得到的錯誤是「顏色無法解析或不是字段」。怎麼了?

另外,我聽說過很多「靜態方法很糟糕」等等,這是一個不好的例子嗎?因爲我發現如果我不使它成爲靜態的,那麼我需要在Shape和Car類中複製getColour方法。如果我應該避免靜態方法,那麼請建議另一種方法來做到這一點。

+0

我建議讓這兩個類都實現一個類似'Colourable'的接口,然後您可以使用'Colourable'作爲參數而不是Object。 – Poriferous

+0

謝謝你們。希望我可以檢查所有答案是有用的。 – fossdeep

回答

3

什麼你要找的是interfaces概念:

public interface Colourable { 
    String getColour(); 
    void setColour(String colour); 
} 

您應該修改ShapeCar類:

public class Shape implements Colourable { 
    public Shape(String colour) { 
     this.colour = colour; 
    } 

    private String colour; 

    public String getColour() { 
     return colour; 
    } 

    public void setColour(String colour) { 
     this.colour = colour; 
    } 
} 

(請注意,我做了colour私人領域;這是通常的做法,並稱爲encapsulation

你可以ñ定義靜態方法作爲

public static String getColour(Colourable item) { 
    return item.getColour(); 
} 

和靜態方法是絕對不差,但在這種情況下,方法本身是有點多餘,因爲如果你已經有一個Colourable,你知道你可以打電話.getColour()得到它顏色。更有用的方法是

public static boolean isRed(Colourable item) { 
    return "red".equals(item.getColour()); 
} 
+0

對不起 - 混合語言。 – Glorfindel

+0

看完接口後,看看你的例子,我仍然有點困惑。我的代碼的整個想法是消除重複的代碼。也就是說,我的整個程序中只有一個getColour()。但看起來現在Shape中有一個,在Car中也必須有一個。那麼如果他們在那裏,那麼製作界面有什麼意義呢?有沒有其他的方式去做我想要的?我想我的原始問題已改變。在我爲不同對象類型獲取顏色的情況下,如何消除重複代碼? – fossdeep

+0

重複的代碼並不總是一件壞事。在你最初的例子中,兩個類都有'public String color;'。這是否也算作重複?大多數Java程序員會說不 - 但他們會對我的getter和setter說同樣的話。唯一的其他選擇(在Java中)是讓這兩個類都從一個通用的超類繼承,但這有概念上的問題。 – Glorfindel

1

好像你試圖使用duck typing,這不是Java的工作原理。

最簡單的事情,恕我直言,將是定義一個接口來處理顏色。例如:

public interface Colourful { 
    public String getColour(); 
} 

public class Shape implements Colorful { 

    private String colour; 

    public Shape(String colour) { 
     this.colour = colour; 
    } 

    @Override 
    public String getColour() { 
     return colour; 
    } 
} 

public class Car { 

    private String colour; 

    public Car (String colour) { 
     this.colour = colour; 
    } 

    @Override 
    public String getColour() { 
     return colour; 
    } 
} 

另外,如果你不想改變ShapeCar,你可以使用反射來提取colour場,但是這通常被認爲是一個壞主意,你可能會更好不使用它:

public static String getColour(Object o) { 
    Field colourField; 
    try { 
     colourField = o.getClass().getField("colour"); 
    } catch (NoSuchFieldException e) { 
     // No such field 
     return null; 
    } 

    Object colourValue; 
    try { 
     colourValue = colourField.get(o); 
    } catch (IllegalAccessException e) { 
     // The field isn't public 
     return null; 
    } 

    if (!(colourValue instanceof String)) { 
     // The field isn't a String 
     return null; 
    } 

    return (String) colourValue; 
} 
0

引發錯誤的原因是Object沒有顏色字段。我不會推薦它,但如果你想繼續使用這個設計,你可以創建一個名爲ShapeCarParent的類(在這種情況下使用,因爲我沒有看到兩者之間有明確的關係),並且這兩個類都繼承了它,然後換getColour,就像這樣:

public class ShapeCarParent{ 
    public String colour; 
} 

public class Car extends ShapeCarParent 
public class Shape extends ShapeCarParent 

public class Colour { 

    public static String getColour(ShapeCarParent item) { 
     return item.colour; 
    } 
} 

這仍然是風格非常不好,所以你也可以使用一個接口,然後在每個類中實現。

public interface ColorProperties{ 
    public String getColour(); 
} 
public class Car implements ColorProperites{ 
    public String getColour() { 
     return colour; 
    } 

} 
public class Shape implements ColorProperites{ 
    public String getColour() { 
     return colour; 
    } 
} 

希望這會有所幫助。

1

你可以「統一」ShapeCar。一般有兩種方法:

讓我們來看看兩者。

繼承:當一個類繼承Porsche(或者,在Java語法,extends)一類Car,你建立一個「是」的關係。在這種情況下:Porsche is-a Car。現在,當你使用對象引用時,魔法就會起作用。現在,您可以編寫這樣的事:

Car c = new Porsche(); 

由於Porsche擁有一切,一個Car有(加在上面的一些東西),你可以看到一個Porsche作爲Car(每個PorscheCar,但每件CarPorsche)。仔細閱讀我的最後一句話,很明顯,下列不工作,事實上,產生一個編譯錯誤:

Porsche p = new Car(); 

你現在可以做的是寫一個方法,期望一個Car並傳入a Porsche(因爲每個PorscheCar)。

回到你的例子。爲了得到這個工作,你可以爲ShapeCar定義一個共同的父類,我們稱之爲Colourable並給它一個方法public Colour getColour()。然後,您可以簡單地將getColour(Object item)方法更改爲getColour(Colourable c)

記住我說的關於「是 - 一個」關係的事情嗎?問問自己:是不是每個Shape a Colourable?是每個Car a Colourable?爲什麼CarShape都在同一個桶中(Colourable)?如果Car已經有父級,例如Vehicle?該解決方案是次優的。

接口:這是接口發揮作用。接口保證,某些方法存在。您可以簡單地將Colourable作爲界面,包含方法public Colour getColour(),而不是定義共同父類Colourable。現在ShapeCar可以implements這個接口。這迫使你在這兩個類中實現這個方法。美:你可以像類一樣使用接口。這意味着您的getColour(Colourable c)的實施不需要更改。

欲瞭解更多詳情,請閱讀提供的教程InheritanceInterfaces

相關問題