我有这样的代码:
String stringRef = new String("Java"); // (1)
System.out.println("(2): " + stringRef.getClass()); // (2)
System.out.println("(3): " + stringRef.length()); // (3)
Object objRef = stringRef; // (4)
// System.out.println("(5): " + objRef.length()); // (5) Not OK.
System.out.println("(6): " + objRef.equals("Java"));
为什么我不能在第(5)行中调用length()
;在第(6)行中将equals()
调用哪个类?
答案 0 :(得分:1)
equals
上声明 Object
,因此您可以调用它; length
不是objRef
。编译器不会尝试确定{{1}}引用的确切对象类型;它仅适用于它是一个对象的知识。
Java编译器基于点运算符左侧表达式的静态类型静态地解析要调用的方法的签名。多态和动态调度的概念仅适用于调用哪种重写方法的解析。
答案 1 :(得分:0)
你不能这样做,因为子类的方法不在你的超类中。在这种情况下,尽管String是Object的子类,因为未在java.lang.Object类中声明length(),因此无法在其实例上调用length。
然而,equals()方法在字符串类中被覆盖,因此将调用字符串的equals()
答案 2 :(得分:0)
对于编译器,objRef
是Object
的实例,它没有任何名为length()
的方法。另一方面,equals()
是来自Object
的方法,并且在String
中继承,这就是程序正常行为的原因。
答案 3 :(得分:0)
length()方法是Strings独有的。通过将其分配给Object,Java不再知道它是String。
古老的陈词滥调:所有圆圈都是形状,并非所有形状都是圆形。
如果您执行以下操作,它将起作用:
System.out.println("(5): " + ((String)objRef).length());
在这里首先对字符串进行类型转换,然后调用length()。
答案 4 :(得分:0)
如果您有Type
引用,则只能调用方法或访问Type
公开且可见的字段,即Type
自己的方法或Type
的公共方法。 1}}超级班。
在这种情况下,Object定义方法equals
和许多其他方法,因此您可以使用它们。
答案 5 :(得分:0)
它是引用的类型,而不是实际的对象,它定义了所有可以访问的方法。所以你不能使用超类引用来访问子类方法,尽管你的超类引用持有子类对象。