2015-07-11 299 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

相关问题