Java 对使用多态性遍历类层次结构感到困惑

Java 对使用多态性遍历类层次结构感到困惑,java,polymorphism,Java,Polymorphism,假设我有一个名为Fish的超类和一个名为Tuna的子类。我不明白为什么会这样: Fish f; Tuna t = new Tuna(); f=t; // I am confused about this statement f.swim(); // (Tuna's swim method is invoked) 为什么fish变量被允许“参与”(因为缺少更好的短语)更专业的金枪鱼对象?我明显错误的“noob OOP Java brain”的工作方式是: 金枪鱼是一种鱼。鱼是金枪鱼不好。因

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

Fish f;
Tuna t = new Tuna();

f=t;  // I am confused about this statement
f.swim();  // (Tuna's swim method is invoked)
为什么fish变量被允许“参与”(因为缺少更好的短语)更专业的金枪鱼对象?我明显错误的“noob OOP Java brain”的工作方式是:

金枪鱼是一种鱼。鱼是金枪鱼不好。因此f=t不应该是正常的,t=f应该是正常的。但从我上面的例子来看,情况正好相反

非常感谢你在这方面的帮助。我为我的无知提前道歉,因为我才刚刚开始学习Java

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


名为f的变量属于Fish类型,因此,允许包含位于名为t的变量内部的数据值(对象引用),因为t指的是金枪鱼对象,因此是f使用的兼容类型。它是兼容的,因为金枪鱼是鱼。

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

赋值只是将右侧表达式的值复制到左侧的变量。这就是它的全部功能

换言之:你可以对
鱼做任何事,你也可以对
金枪鱼做任何事。因此,
t
的值不存在,因此:

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

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

String s = "foo";
f = s;
f.swim();
那就没有意义了,因为你不能让
字符串
游泳


类型安全规则确保您永远不能尝试调用方法(或访问字段)并发现您正在使用的类型的方法/字段根本不存在。
金枪鱼
扩展了
这一事实意味着你可以对“普通”鱼做任何事情,你也可以对金枪鱼做任何事情。
f
变量的值是一个参考值。可以是空引用,也可以是对任何“是鱼”的对象的引用。由于
Tuna
对象是
Fish
对象,因此可以从
t
复制值,该值必须是空引用或对
Tuna
对象的引用

赋值只是将右侧表达式的值复制到左侧的变量。这就是它的全部功能

换言之:你可以对
鱼做任何事,你也可以对
金枪鱼做任何事。因此,
t
的值不存在,因此:

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

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

String s = "foo";
f = s;
f.swim();
那就没有意义了,因为你不能让
字符串
游泳


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

你很接近,但你在一句话中就错了

金枪鱼是一种鱼

我同意——这意味着f=t(鱼=金枪鱼)的说法是正确的

鱼是金枪鱼不好

我同意——这意味着声明t=f(金枪鱼=鱼)是不正确的

。因此f=t不应该是正常的,t=f应该是正常的

我不同意,因为你的上级只是说了一些相反的话。 在上一篇文章中,你说每一条鱼都是金枪鱼(t=f),而不是每一条金枪鱼都是鱼(f=t)——这显然是错误的

如果金枪鱼是鱼,那么F=T,因为任何金枪鱼都是鱼。但我们不能说每条鱼都是金枪鱼,对吗


你必须记住
=
并不意味着平等(java中
=
就是平等),为了更好地理解,试着从右到左阅读这些状态表。

你很接近,但你在一条语句中就错了

金枪鱼是一种鱼

我同意——这意味着f=t(鱼=金枪鱼)的说法是正确的

鱼是金枪鱼不好

我同意——这意味着声明t=f(金枪鱼=鱼)是不正确的

。因此f=t不应该是正常的,t=f应该是正常的

我不同意,因为你的上级只是说了一些相反的话。 在上一篇文章中,你说每一条鱼都是金枪鱼(t=f),而不是每一条金枪鱼都是鱼(f=t)——这显然是错误的

如果金枪鱼是鱼,那么F=T,因为任何金枪鱼都是鱼。但我们不能说每条鱼都是金枪鱼,对吗


您必须记住,
=
并不意味着相等(java中的
=
是相等的),为了更好地理解,请尝试从右到左阅读这些状态表。

您有Fish超类,它有swim方法,而Tuna是Fish的子类。 所以 金枪鱼是鱼,没关系 但鱼是金枪鱼:不好。 同样的 您可以将金枪鱼参考指定给鱼参考,但鱼参考不能指定给金枪鱼。 所以


你们有一个有游泳方法的鱼类超类,而金枪鱼是鱼类的子类。 所以 金枪鱼是鱼,没关系 但鱼是金枪鱼:不好。 同样的 您可以将金枪鱼参考指定给鱼参考,但鱼参考不能指定给金枪鱼。 所以


绳子不会游泳吗?天啊!我开悟了!绳子不会游泳吗?天啊!我开悟了!谢谢,是的,我同意,readi