假设我有一个名为Fish的超类,以及一个名为Tuna的子类。我不明白为什么会这样:
Fish f;
Tuna t = new Tuna();
f=t; // I am confused about this statement
f.swim(); // (Tuna's swim method is invoked)
为什么鱼变量允许“参与”(因为缺少更好的短语)更专业的金枪鱼对象?我明显错误的“noob OOP Java大脑”的工作方式是:
非常感谢您对此的任何帮助。我提前为我的无知道歉,因为我刚刚开始学习Java。
修改即可。非常感谢下面的所有回复。从他们,我现在明白:
名为f的变量是Fish类型,因此,允许包含位于变量t内的数据值(对象引用),因为t指的是Tuna对象,因此它是兼容的类型f使用。这是兼容的,因为金枪鱼是一种鱼。
答案 0 :(得分:2)
你很亲密,但只有一个陈述你错了。
金枪鱼“是”鱼还可以
我同意 - 这意味着声明f = t(fish = tuna)是正确的。
鱼“是”金枪鱼不行
我同意 - 这意味着声明t = f(tuna = fish)是不正确的。
。因此f = t应该不行,t = f应该没问题
我不同意,由于你上面的陈述,你刚才说了一些相反的话。 在最后一次,你说每条鱼都是金枪鱼(t = f)而不是每条金枪鱼都是鱼(f = t) - 这显然是错误的。
如果金枪鱼是鱼,那么F = T因为任何金枪鱼都是鱼。但我们不能说每条鱼都是金枪鱼吗?
你必须记住,=
并不意味着平等(whitch ==
在java中),为了更好地理解,请尝试从右到左阅读这些状态。
答案 1 :(得分:1)
f
变量的值是引用。这可以是空引用,也可以是对“是鱼”的任何对象的引用。由于Tuna
对象是Fish
对象,因此可以复制t
中的值,该值必须是空引用或对Tuna
对象的引用。< / p>
分配只是将右侧表达式的值复制到左侧的变量。就是这样。
换句话说:您可以对Fish
执行任何操作,您可以执行Tuna
。所以t
没有价值:
f = t;
f.swim();
是荒谬的。 (t
当然可以是空引用,但这并不是类型系统中的问题。)总是是一个适当的swim
方法来调用,只要t
非空。
将其与不同类型进行比较。如果我们有:
String s = "foo";
f = s;
f.swim();
然后 没有意义,因为你不能要求String
游泳。
类型安全规则确保您永远不会尝试调用方法(或访问字段)并发现您正在使用的方法/字段根本不存在。 Tuna
延伸Fish
的事实意味着您可以使用“普通”鱼做任何事情,也可以使用金枪鱼。
答案 2 :(得分:1)
你有Fish Super Class游泳方法,Tuna是Fish的子类。 所以 金枪鱼是鱼:好的 但鱼是金枪鱼:不行。 相同 您可以将金枪鱼参考分配给鱼参考,但鱼参考不能参加金枪鱼。 所以
public class Fish {
public void swim(){
System.out.print("Hello Fish");
}
}
public class Tuna extends Fish{
public void swim(){
System.out.print("Hello Tuna");
}
public static void main(String[] ar){
//Case A
Fish f=new Fish();
Tuna t;
t=(Tuna) f;//wrong - it will not cast to tuna object
t.swim();
//Case B //correct
Fish f;
Tuna t=new Tuna();
t=f
t.swim();
}
}