java通过超类引用调用子类方法
我有这样的代码:
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()
# 1 楼答案
您不能这样做,因为子类的方法不在您的超类中。在本例中,虽然String是Object的一个子类,但length()不是在java中声明的。对象类无法在其实例上调用长度
然而,equals()方法在string类中被重写,因此将调用string的equals()
# 2 楼答案
对于编译器,
objRef
是Object
的一个实例,它没有任何名为length()
的方法。另一方面,equals()
是一个来自Object
的方法,并在String
中继承,这就是程序行为正确的原因# 3 楼答案
当有
Type
引用时,只能调用对Type
可见的公共方法或访问字段,即Type
自己的方法或Type
超类的公共方法在本例中,对象定义了方法
equals
和许多其他方法,因此您可以使用它们# 4 楼答案
定义所有可访问方法的是引用类型,而不是实际对象。因此,即使超类引用包含子类对象,也无法使用超类引用访问子类方法
# 5 楼答案
equals
在Object
上声明,因此您可以调用它length
不是。编译器不会尝试确定objRef
引用的对象类型;它只有在知道它是一个物体的情况下才起作用Java编译器根据点运算符左侧表达式的静态类型,静态解析要调用的方法的签名。多态性和动态分派的概念仅适用于要调用的重写方法的解析
# 6 楼答案
length()方法是字符串特有的。通过将其分配给一个对象,Java不再知道它是一个字符串
老生常谈:所有的圆都是形状,不是所有的形状都是圆
如果您执行以下操作,它将起作用:
在这里,您首先键入一个字符串,然后调用length()