したがって、これをまとめると、ミルク、パン、肉は食品のサブクラスである(食品を「拡張」する)ことを意味します。これが事実だと思います。もしそうなら、それがコンパイルされる理由です。
つまり、牛乳、パン、肉は食品として扱うことができますが、それらの奥深くは異なります(つまり、1つはパン、1つは牛乳、もう1つは肉であり、それぞれが食品のメンバー変数に加えて独自のメンバー変数を持っています。アイテム)
Javaでは、変数fはFoodおよびFoodのサブクラスを受け入れます。ただし、通過する食品(肉、牛乳、パンを含む)は、特定の種類の食品を無視して、食品オブジェクトとして扱われます。
それらがどのような種類のFoodサブクラスであるかを正確に知りたい場合は、instanceof演算子を使用して調べてから、アクションを実行できます。次に、それらを実際の特定のタイプにキャストして、それらのオブジェクトから特定のメソッドを呼び出します。
あなたのコード:あなたがしているのは実際の食料品を返すことだけなので、キャストは必要ありません。Javaは、デフォルトでミルク、パン、肉を食品として扱い、デフォルトで食品の代わりに返品できます。一方、Meat、Bread、またはMilkオブジェクトの特定のプロパティにアクセスする場合は、キャストが必要になります。これらのfは単なる食品ではなく、肉、パン、またはミルクであることをJavaに伝える必要があります。たとえば、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");
}