假设我有一个名为Fish的超类和一个名为Tuna的子类。我不明白为什么这样做:

Fish f;
Tuna t = new Tuna();

f=t;  // I am confused about this statement
f.swim();  // (Tuna's swim method is invoked)


为什么允许鱼变量“涉及”(为了更好的用语)更专业的金枪鱼对象?我明显错误的“菜鸟OOP Java大脑”的工作方式是:

金枪鱼“是”鱼是可以的。鱼“是”金枪鱼不好。因此,f = t不应为OK,而t = f应为OK。但是从上面的例子来看,情况恰恰相反!

非常感谢您对此提供的任何帮助。我为自己的无知向您致歉,因为我才刚刚开始学习Java。

编辑。非常感谢您在下面的所有回复。从他们那里,我现在了解到:

名为f的变量是Fish类型,因此,它被允许包含位于变量t内的数据值(对象引用),因为t表示金枪鱼对象,因此是f的兼容类型。因为金枪鱼是鱼,所以很兼容。

最佳答案

f变量的值是参考。这可以是空引用,也可以是对“是鱼”的任何对象的引用。由于Tuna对象是Fish对象,因此可以从t复制值,该值必须为空引用或对Tuna对象的引用。

分配只是将右侧表达式的值复制到左侧变量。这就是全部。

换句话说,您可以对Fish做任何事情,也可以对Tuna做任何事情。因此,没有t这样的值:

f = t;
f.swim();


是荒谬的。 (当然,t可以是空引用,但是在类型系统中这并不是问题。)只要swim为非空,总是会有一个合适的t方法来调用。 。

将其与其他类型进行比较。如果我们有:

String s = "foo";
f = s;
f.swim();


那就没有意义了,因为您不能要求String游泳。

类型安全规则确保您永远不会尝试调用方法(或访问字段)并发现您使用的是该方法/字段根本不存在的类型。 Tuna扩展Fish的事实意味着您可以用“一般”鱼做任何事情,也可以用金枪鱼做任何事情。

09-16 00:38