假设我有一个名为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
的事实意味着您可以用“一般”鱼做任何事情,也可以用金枪鱼做任何事情。