Java 从父类类型方法返回子对象

Java 从父类类型方法返回子对象,java,class,oop,methods,Java,Class,Oop,Methods,我正在尝试编写一个方法,创建随机植物,并将创建的植物的对象返回为plant。在下面的示例中,方法createPlant()的类型为Plant,并返回子类树的对象。事实证明,我的思维方式是错误的。Eclipse提供的错误是:“此方法必须返回Plant类型的结果”。那么,我应该如何着手创建这样的方法呢 public abstract class Plant { ... } public class Tree extends Plant { ... } public class B

我正在尝试编写一个方法,创建随机植物,并将创建的植物的对象返回为
plant
。在下面的示例中,方法
createPlant()
的类型为
Plant
,并返回子类
树的对象。事实证明,我的思维方式是错误的。Eclipse提供的错误是:“此方法必须返回Plant类型的结果”。那么,我应该如何着手创建这样的方法呢

public abstract class Plant {
    ...
}

public class Tree extends Plant {
    ...
}

public class Bush extends Plant {
    ...
}

public class Map {
    private Plant plant;
    ...
    public static Plant createPlant(float x, float y) { // This method must return a result of type Plant
        Random generator = new Random();            
        switch (generator.nextInt(2)) {
            case 0:
                return new Tree(x, y);
            case 1:
                return new Bush(x, y);
        }
    }
}

不,从面向对象的角度来看,这是绝对正确的。植物是一个整体,而树在某种程度上是特殊的


主要的一点是,树也是一个植物(is-a-relation),因此返回植物的方法可以返回至少与植物一样通用但可能更专业的任何内容。

添加默认情况下的
null

    switch (generator.nextInt(2)) {
        case 0:
            return new Tree(x, y);
        case 1:
            return new Bush(x, y);
        default:                         // Requires default case
            return null;
    }
或者创建一个虚拟
NoPlant

  public class NoPlant extends Plant {
     ...
  }
现在用这种方法

    switch (generator.nextInt(2)) {
        case 0:
            return new Tree(x, y);
        case 1:
            return new Bush(x, y);
        default:                         // Requires default case
            return new NoPlant();
    }

--编辑--

这样也可以试试

    int random=generator.nextInt(2); // return either 0 or 1

    if(random==0){
        return new Tree(x,y);
    }else{
        return new Bush(x, y);
    }

张贴一个完整的例子,再现问题。我觉得你贴的很好。
是一棵
植物
。不是吗。感谢JB Nizet指出了正确的方向,很抱歉第一次没有提供完整的问题。问题在于没有定义默认情况。我该怎么处理这个问题呢?我该保持原样,还是最好把它去掉?我不明白你想做什么。树的类型为Plant,因此您返回的是一种植物类型;如果要返回
新工厂
,必须通过创建匿名类来扩展实例删除它,或者在编辑问题并发布实际存在问题的代码后自己回答它。它不会回答问题。OP的代码很好,这个NoPlant想法是个坏主意。@jbnitet实际上OP正在寻找一些未定义的默认值。@Nignas感谢您的编辑,但请记住
null
不是
Plant
类型。@nignas
null instanceof Plant
将返回
false
,现在它回答了问题。最好的解决方案是抛出一个异常:
抛出新的IllegalStateException(“不应该发生:nextInt(2)不应该生成一个既不是1也不是2的int”)。这样,如果开发人员更改为nextInt(3)并忘记在开关中添加case,他将得到一条清晰、有意义的错误消息。