Java 你需要一个 else 之后的 else 如果?另外,是否需要转换扩展类



我有以下代码。 为什么会这样?选角有必要吗?

static public Food createMeal(Food f)
      throws Exception
  {
    if (f instanceof Bread)
    {
      return (Bread) f;
    }
    else if (f instanceof Meat)
    {
      return (Meat) f;
    }
    else if (f instanceof Milk)
    {
      return (Milk) f;
    }
    throw new Exception("NotAFood!");
  }

不,向下投射是不必要的,并且实际上是无操作:

  1. instanceof检查确保向下的投射不会失败;
  2. 每个向下的引用都会立即被return语句向上转换回Food

该函数可以像这样编写得更紧凑:

  static public Food createMeal(Food f) throws Exception {
    if ((f instanceof Bread) || (f instanceof Meat) || (f instanceof Milk)) {
      return f;
    } else {
      throw new Exception("NotAFood!");
    }
  }

话虽如此,在条件语句中使用instanceof通常是设计不佳的标志。 想象一下,添加一个新的Food子类。现在,您必须重新访问代码中以这种方式使用instanceof的每个位置,并对其进行适当的修改。

更好的设计是在基类中定义一个合适的虚函数,并在派生类中重写它。

这里不需要

else,因为如果满足以前的条件,那么return将简单地转义整个方法:

if (f instanceof Bread)
{
  return (Bread) f;
}
if (f instanceof Meat)
{
  return (Meat) f;
}
if (f instanceof Milk)
{
  return (Milk) f;
}
throw new Exception("NotAFood!");

不,这里不需要向下投掷。实际上,您可以像这样编写等效函数:

static public Food createMeal(Food f) throws Exception {
    if(f instanceof Bread || f instanceof Meat || f instanceof Milk) {
        return f;
    }
    throw new Exception("NotAFood!");
}

因此,如果编译,则意味着牛奶,面包和肉类是食物的子类(它们"扩展"了食物(。我假设是这种情况。如果是这样,那么这就是编译的原因。

现在,这意味着牛奶,

面包和肉类可以被视为食物,但它们的内心深处是不同的(即一个是面包,一个是牛奶,一个是肉,每个都有自己的特殊成员变量在食品项目之上(

在爪哇中,变量 f 接受任何 Food 和 Food 的任何子类。但是,您传递的任何食物(包括肉类、牛奶和面包(都将被视为食物对象,而不考虑它们的具体食物种类。

如果要准确查找它们是什么类型的 Food 子类,可以使用 instanceof 运算符来查找并采取行动。然后,将它们强制转换为其实际的特定类型,以从这些对象调用特定方法。

你的代码:你所做的只是返回一个实际的食物项目,所以不需要铸造。Java 默认将牛奶、面包和肉类视为食物,默认情况下可以代替食物项返回。另一方面,如果您想访问肉、面包或牛奶对象的特定属性,则需要强制转换。你需要告诉java,这些f不仅仅是一种食物,而是一种肉、面包或牛奶。例如,如果你的 Milk 类有一个 getFatPercent(( 方法,那么你需要 ((Milk(f(.getFatPercent((

假设 Food 可以有更多的子类,你的代码等效于:

static public Food createMeal(Food f) throws Exception {
    if(f instanceof Milk || f instanceof Meat || f instanceof Bread)
        return f;
    else
        throw new Exception("Not a valid Food");
}

不需要强制转换。不,你不需要 else 在 else 之后 if 。事实上,else 总是可选的

请注意,else语句并不总是可选的。例如,下面的代码无法编译,因为没有else语句!编译器会感到困惑,因为 check(( 方法必须返回一个boolean,并认为存在 if 语句和 else-if 语句都无法执行的情况,因此 check(( 永远不会返回boolean

static boolean check(int x) {
    if (x < 5) {
        return true;
    } else if (x >= 5) {
        return false;
    }
}
public static void main(String[] args) {
    check(5);
}

最新更新