有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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()


共 (6) 个答案

  1. # 1 楼答案

    您不能这样做,因为子类的方法不在您的超类中。在本例中,虽然String是Object的一个子类,但length()不是在java中声明的。对象类无法在其实例上调用长度

    然而,equals()方法在string类中被重写,因此将调用string的equals()

  2. # 2 楼答案

    对于编译器,objRefObject的一个实例,它没有任何名为length()的方法。另一方面,equals()是一个来自Object的方法,并在String中继承,这就是程序行为正确的原因

  3. # 3 楼答案

    当有Type引用时,只能调用对Type可见的公共方法或访问字段,即Type自己的方法或Type超类的公共方法

    在本例中,对象定义了方法equals和许多其他方法,因此您可以使用它们

  4. # 4 楼答案

    定义所有可访问方法的是引用类型,而不是实际对象。因此,即使超类引用包含子类对象,也无法使用超类引用访问子类方法

  5. # 5 楼答案

    equalsObject上声明,因此您可以调用它length不是。编译器不会尝试确定objRef引用的对象类型;它只有在知道它是一个物体的情况下才起作用

    Java编译器根据点运算符左侧表达式的静态类型,静态解析要调用的方法的签名。多态性和动态分派的概念仅适用于要调用的重写方法的解析

  6. # 6 楼答案

    length()方法是字符串特有的。通过将其分配给一个对象,Java不再知道它是一个字符串

    老生常谈:所有的圆都是形状,不是所有的形状都是圆

    如果您执行以下操作,它将起作用:

    System.out.println("(5): " + ((String)objRef).length());
    

    在这里,您首先键入一个字符串,然后调用length()