java - 指向子类对象的父类(super class) ref 的类类型是什么?

标签 java class reference subclass superclass

我有以下代码:

1. public class Tester
2. {
3.      public static void main(String[] args)
4.      {
5.          A a = new B();
6.          System.out.println(a.getClass());    //Prints class B       
7.          System.out.println(a instanceof A);  //Prints true
8.          System.out.println(a instanceof B);  //Prints true
9.          System.out.println(a.valA);          //Prints 1
10.         System.out.println(a.valB);          //Compilation error
11.
12.     }
13. }
14.
15. class A
16. {
17.     int valA=1;
18. }
19.
20. class B extends A
21. {
22.     int valB=2;
23. }

第 6 行,它显示 aclass B 类型。然而,当它到达第 10 行时,编译器会产生一个错误:location: variable a of type A

所以我的问题是:现在 a 的类类型到底是什么?为什么 getClass() 显示它是 class B 类型,但编译器在编译期间却将其报错为 A 类型?

而且,既然a instanceof B为真,为什么我不能访问valB


为了让事情更清楚:

编辑:我运行了这条语句:System.out.println(a); 并且输出是 B@36d98810 这以某种方式证明了B类toString()方法被执行了。既然变量 a 可以访问 class B 中的 toString() 方法,为什么它不能访问同样位于 class 中的 valB B?

最佳答案

加州大学伯克利分校的 Jonathan Shewchuk 教授解释了关于 here 的影子.从 18 分钟开始。 (如果链接更改,只需谷歌搜索 CS 61B 第 15 讲:更多 Java)

简而言之,变量有两种类型,静态类型和动态类型。

Static type is its Type at compile time
Dynamic type is its Type at run time.

在你的例子中

A a = new B();

a的静态类型是A,a的动态类型是B。

In Java a variable gets its non static methods from dynamic type
(if the method exists in both the parent and child class)
and 
its fields and static methods from the static type.

仅当方法在子类中被重写时,这在 C# 中才是正确的

更新: 线路

a instanceof A

告诉你 a 的动态类型是类型 A 还是 A 的子类

更新 2: 一个说明这一点的例子

public class PlayGround {

    public static void main(String[] args) {
        Animal a = new Dog();
        System.out.print(a.name);// displays animal
        System.out.print("\r\n");
        a.MakeStaticSound();// displays static animal sound
        System.out.print("\r\n");
        a.MakeSound();// displays bow wow

    }

}

class Animal {
    public String name = "animal";

    public void MakeSound() {
        System.out.print("animal sound");
    }

    public static void MakeStaticSound() {
        System.out.print("static animal sound");
    }

}

class Dog extends Animal {
    public String name = "dog";

    public void MakeSound() {
        System.out.print("bow wow");
    }

    public static void MakeStaticSound() {
        System.out.print("static bow wow");
    }

}

请注意,调用 a.MakeStaticSound() 的可读性和首选方式是 Animal.MakeStaticSound()

关于java - 指向子类对象的父类(super class) ref 的类类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27177171/

相关文章:

java - 使用 Spring 引导将 list<object> 传递给 thymeleaf

Java:使用导入或显式包/类名?

c++ - 没有通过引用看到对 vector 最后一个元素的操作的影响

c++ - 三元运算符 : Compiler does not emit return reference of local variable warning

javascript - 在 QZ-Print Java Applet 中调用函数在 PHP 中不起作用

java - Spring Security Java Config 未生成注销 url

java - 类的对象属性

Python MyHashTable 类 : search method with linear probing

c++ - 如何在 if 语句中使用 dynamic_cast

arrays - 我不明白这个 Perl 语法,有人知道吗?