将子类的对象类型转换为父类时,对象的变量会发生什么情况?

When typecasting an child class's object to parent class, what happens with the variables of the object?

提问人:Akanksha Makkar 提问时间:4/17/2023 最后编辑:VGRAkanksha Makkar 更新时间:4/17/2023 访问量:124

问:

class HelloWorld 
{
    public static void main(String[] args) 
    {
         A a =  new B();
         System.out.println(a.getX()); 
         a.show();
    }
}

class A {
    int x = 10;
    
    public A() {
    }
    
    public int getX() {
        return x;
    }
    
    public void show(){
        System.out.println("A show");
    }   
}

class B extends A{
    int x = 20 ;
    
    public B() {
        super();
    }
    
    @Override
     public void show(){
        System.out.println("B show");
    }
}

为什么输出是这样的?

10
B秀

我理解“B Show”。由于该对象属于 B 类,因此它将调用在 B 中重写的方法。但是不明白为什么它在输出中打印“10”,即使 B 的对象值 x 等于 20。 请帮助我理解这一点。

java oop 继承 转换 typecasting-operator

评论

2赞 VGR 4/17/2023
int x = 10;和 是两个不同的字段。第二个不会以任何方式覆盖第一个。方法可以被覆盖;字段不能。也就是说,如果 B 的构造函数包含(如果没有 - 代码不声明新字段至关重要!),您将看到您期望看到的内容。int x = 20;x = 20;int
1赞 nomoa 4/17/2023
stackoverflow.com/questions/10722110/ 的副本...
0赞 Joachim Sauer 4/17/2023
回答标题中的字面问题:字段没有任何变化。事实上,物体根本没有发生任何事情!在 Java 中强制转换引用完全不会影响它引用的对象。它仅更改编译时类型,这可能会影响可以调用的方法。在运行时,强制转换只不过是检查它是否被允许:这就是 JVM 真正所做的一切。

答:

0赞 rzwitserloot 4/17/2023 #1
  • 所有 B 都是 A,带有额外的花里胡哨。这就是意思。extends A {}
  • 字段免费继承。事实上,由于字段没有实现(仅定义它们就是其结束的地方),因此,如果在子类型中声明具有相同名称的字段,则现在有 2 个字段。因此,您的 B 实例有 2 个字段。它们都是命名的,但完全是独立的字段。在实际代码中,你永远不应该这样做;这非常令人困惑。x
  • 从 B 类中删除意味着 B 仍然有一个名为类型的字段 - 它从 A 继承该字段。这只是意味着它现在没有第二个字段,该字段也被命名为 类型。int x;intxxint

java 中方法的“名称”不仅仅是方法名称,还包括参数类型。除非它们匹配,否则无法覆盖。换言之:

class A { 
  void foo(int x) {}
}

class B extends A {
  void foo(long y) {}
}

这里 B 的方法与 A 的方法不同,因此 foo 不会覆盖。如果你在上面打一个,你会得到一个编译器错误。不可能使 B 的 foo 代码运行,因为给定此处的引用( - 指针,变量指向对象)的类型为 ,编译器不知道 B 的方法,因此不可能在此处调用它。使 B 方法成为覆盖,并且会调用 B 的,而不是 A 的,因为 java 会进行动态调度。foo@OverrideA a = new B(); a.foo(5);aAfoo(long)void foo(int x)A a = new B(); a.foo(5);

同样的原则也适用于字段。With 是指在类 A 中定义的字段。A a = new B();a.xx