Java 对子类对象的超类引用

Java 对子类对象的超类引用,java,inheritance,reference,polymorphism,Java,Inheritance,Reference,Polymorphism,我感到困惑:我从一个学习资源中引用了下面的引语(以及它们出现的章节的标题),但这些引语在我看来似乎相互矛盾 超类引用和子类对象 “决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型” 重写的方法支持多态性 “正是被引用对象的类型(而不是引用变量的类型)决定了将执行哪个版本的重写方法” 如果classB扩展了ClassA,并且您有: ClassA a = new ClassB (); 使用a变量,您只能访问ClassA中定义的成员(或ClassA的超类或ClassA实现的接口)。

我感到困惑:我从一个学习资源中引用了下面的引语(以及它们出现的章节的标题),但这些引语在我看来似乎相互矛盾

超类引用和子类对象 “决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型”

重写的方法支持多态性 “正是被引用对象的类型(而不是引用变量的类型)决定了将执行哪个版本的重写方法”


如果classB扩展了ClassA,并且您有:

ClassA a = new ClassB ();
使用
a
变量,您只能访问
ClassA
中定义的成员(或
ClassA
的超类或
ClassA
实现的接口)。您无法访问
ClassB
中定义的成员,该成员未在
ClassA
中定义(除非您将
a
强制转换为
ClassB


但是,调用在
ClassB
中重写的
ClassA
方法将执行
ClassB
方法。

超类引用和子类对象

假设Child扩展了Parent,让我们看一下:

Parent obj = new Child();
现在,如果我们尝试使用
obj
,我们只能使用父类中指定的行为(方法)。我们不能使用子类中的任何新方法

但是,假设父级和子级都有一个方法
公共字符串whoAmI()

家长:

 return "Parent";
儿童:

return "Child";
现在,如果我们运行以下代码:

Parent obj1 = new Child();
Parent obj2 = new Parent();

System.out.println(obj1.whoAmI());
System.out.println(obj2.whoAmI());
输出:

Child
Parent
   i 90
   j 100
   Child show ..
   Show inside Child start
   10 20
   Show inside Child END

因此,您只能访问引用它的类中的方法(第一个代码段中的父类)。但是如果您在类中重写了它,它被实例化为(第一个代码段中的Child),并且在子类中重写了父类中的方法,那么调用父类中的方法将调用子类中重写的方法。

请看下面的程序

class SuperMem{
    int i = 90;
    int j = 100;

    void show(){
        System.out.println("parent show..");
        System.out.println("Show inside Parent start");
        System.out.println(i + " " + j);
        System.out.println("Show inside Parent END");
    }
}

class submem extends SuperMem{
    int i = 10;
    int j = 20;
    void show(){
        System.out.println("Child show ..");
        System.out.println("Show inside Child start");
        System.out.println(i + " " + j);
        System.out.println("Show inside Child END");

    }
}

public class SuperMemDemo {
    public static void main(String[] args) {
        SuperMem m = new SuperMem();
        submem s = new submem();
        m = s;

        System.out.println("i " + m.i);
        System.out.println("j " + m.j);
        m.show();
    }

}
输出:

Child
Parent
   i 90
   j 100
   Child show ..
   Show inside Child start
   10 20
   Show inside Child END

方法通过动态分派方法(即在运行时)进行解析。分析输出,您将从完整的参考资料Herbert Schildt中获得上述两个语句的含义,假设我们有两个类

class车辆{
公共车道(){
System.out.println(“车辆正在移动”);
}
}
class Car扩展了车辆{
公共车道(){
System.out.println(“汽车正在移动”);
}
公共音乐{
System.out.println(“汽车正在播放音乐”);
}
}
“决定可以访问哪些成员的是引用变量的类型,而不是它所引用的对象的类型”

这意味着如果我们有这样的代码
车辆=新车()
使用
vehicle
对象,我们可以调用
drive()
,但不能调用
playMusic()
,因为
vehicle
的类型是
vehicle

“是被引用对象的类型(而不是引用变量的类型)决定将执行哪个版本的重写方法”

这意味着如果我们有这样的代码

车辆=新车();
车辆行驶();

它将打印“Car is Moving”而不是“Vehicle is Moving”,因为存储在
Vehicle
中的对象是
Car

的一个实例。。。你是从哪里得到这些的?你问题的一部分可能是重复的:它不是那个问题的完全重复。我认为这会增加更多。@Jayan-这不是重复的。相反,这个问题纯粹是关于多态性的。谢谢大家-我现在有了更好的理解。Anubian Noob,这些引语来自一本教科书,我发现大部分都很清楚。