让方法接受不同的对象作为参数

时间:2015-07-11 16:05:05

标签: java

首先,我将提供我的示例代码。

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,那么" color"以粗体显示为错误。我得到的错误是"颜色无法解析或不是字段"。怎么了?

另外,我听说很多"静态方法都很糟糕"这是一个坏的情况吗?因为我发现如果我不能使它静止,那么我需要在Shape和Car类中复制getColour方法。如果我应该避免静态方法,那么请建议另一种方法来做到这一点。

4 个答案:

答案 0 :(得分: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());
}

答案 1 :(得分:1)

好像你试图使用duck typing,这不是Java的工作方式。

最简单的做法是恕我直言,定义一个界面来处理颜色。 E.g:

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;
}

答案 2 :(得分:1)

你可以"统一" ShapeCar。有两种通用方法:

让我们看看两者。

继承:当一个类Porsche继承(或者,在Java语法中,extends)一个类Car时,你建立一个"是-a"关系。在这种情况下:Porsche是-a Car。现在,当您使用对象引用时,魔法就会起作用。你现在可以这样写:

Car c = new Porsche(); 

由于Porsche包含所有内容,Car包含(加上一些内容),您可以看到PorscheCar(每个Porsche }是Car,但不是每个Car都是Porsche)。仔细阅读我的最后一句,很明显,以下内容不起作用,实际上会产生编译错误:

Porsche p = new Car();

您现在可以做的是编写一个方法,该方法需要Car并传入Porsche(因为每个Porsche都是Car)。

回到你的榜样。为了实现这一点,您可以为ShapeCar定义一个公共父类,让我们称之为Colourable并为其指定方法public Colour getColour()。然后,您只需将getColour(Object item)方法更改为getColour(Colourable c)

记得我说的关于" is-a"关系?问问自己:每个ShapeColourable吗?每个CarColourable吗?为什么CarShape都在同一个存储区(Colourable)中?如果Car已经有父类,例如,该做什么Vehicle?该解决方案不是最佳的。

接口:这是接口发挥作用的地方。接口保证存在某些方法。您可以简单地将Colourable编写为包含方法Colourable的接口,而不是定义公共父类public Colour getColour()。现在ShapeCar可以implements此界面。这会强制您在两个类中实现此方法。美:你可以像类一样使用接口。这意味着您getColour(Colourable c)的实施不需要改变。

有关详细信息,请阅读InheritanceInterfaces上提供的教程。

答案 3 :(得分: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;
    }
}

希望这有帮助。