在Java中,我能通过超类引用访问子类对象的属性吗?

4
假设我有一个类叫做Food,在构造函数中有价格、卡路里数量和描述属性。我还有一个Food的子类叫做Burger,Burger有一个额外的属性,用于表示肉的类型。
现在,如果我创建了一个包含Burger实例的Food实例数组,我能通过这个数组访问肉的类型属性吗?
抱歉如果这有点令人困惑,但我想知道如何在父类和子类对象的数组中访问它们的属性。我正在使用Java编程语言。

你需要进行强制类型转换:((Burger)foods[index]).getMeatType - Jean-François Savard
构造函数没有属性,只有对象实例才有属性。你的问题应该是“我能通过超类引用访问子类对象的属性吗?” - Jim Garrison
谢谢,你能否尝试解释一下到底发生了什么?是将Food实例转换为Burger实例吗?感谢澄清。所以构造函数有属性,对象有属性? - user4205912
不完全正确。属性和特性是同一回事。构造函数是可执行的方法,只有对象实例才有属性(静态属性实际上属于类本身)。请参见下面我的答案,讨论您的问题。 - Jim Garrison
2个回答

1

即使一个 Burger 存储在 Food 数组中,你仍然可以访问它的属性。首先,你需要将其转换为 Burger 类型,以便程序知道它是什么类型。由于数组中的不是所有对象都是 Burger,因此最好先检查其类型。可以像这样:

Food[] myFoods; //your food array
if (Burger.isInstance(myFoods[0])) { //check that the Food is a Burger
 ((Burger)myFoods[0]).meatType; //cast the object to a Burger and access its property
}

谢谢!这很有道理。我现在的方式是有两个单独的数组,但现在我可以只有一个对象数组。 - user4205912
@Skistar002 很高兴能帮到你!如果这解决了你的问题,我会非常感激你的点赞或接受。 - nhouser9

0
在您的情况下,子类 Burgermeat 属性是特定于该子类的,因此唯一的选择是将 Food 对象向下转换为 Burger,在您想要访问其特定于 Burger 的属性时进行。如果您的集合(数组)包含不同的子类,则此转换可能会失败,存在很多问题。
Food[] foods = new Food[n];
Food[0] = new Burger(...);
Food[1] = new Vegetable(...);
Meat m1 = ((Burger)foods[0]).getMeat(); // This is OK
Meat m2 = ((Burger)foods[1]).getMeat(); // ClassCastException

或者更好

for (Food f : foods)
{
    if (f instanceof Burger)
    {
        Meat m = ((Burger)foods[0]).getMeat(); 
        // other Burger-related processing
    }
    else if (f instanceof ...someothersubclass)
    {
         ...

这往往比较脆弱,但是你无法使用多态来简化事情。运行时(动态)分派仅适用于重写的方法。同一类中的重载方法在编译时解析。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接