公共属性和继承Java

 你的念头_780 发布于 2023-02-13 12:57

我正在检查一些Java练习但是我对这个很困惑:

我们有一个具有这种结构的Foo类:

public class Foo {
    public int a = 3;

    public void addFive() {
        a += 5;
    }
}

从Foo继承的Bar类:

public class Bar extends Foo {
    public int a = 8;

    public void addFive() {
        a += 5;
    }
}

还有一个测试类:

public class Test {

    public static void main(String[] args) {
        Foo f = new Bar();
        f.addFive();
        System.out.println(f.a);
    }
}

我认为输出是13,但它是3,我的问题是为什么?..

3 个回答
  • 您需要知道Java中的后期绑定(在运行时基于实际对象查找方法体的多态性机制)仅适用于方法,而不适用于字段.

    因此,如果你有Foo像我们的情况那样保存从Foo派生的类型的对象的基类型的引用Bar

    Foo f = new Bar();
    

    那么f.field你将使用Foo类中的字段(这里没有多态行为).
    但是如果你使用f.someMethod()那么感谢运行时的后期绑定Java将从类中找到并执行此方法的代码Bar(因为f保存了Bar对象的内容).

    所以在你的代码中

    Foo f = new Bar();//you are creating reference of type Foo to instance of Bar
    f.addFive();//body of this method will increment `a` declared in `Bar`
    System.out.println(f.a);//here you are using `a` declared in Foo.
    

    如果使用类型引用,则可以aBar类中获取值Bar.

    System.out.println(((Bar)f).a);//prints 13.
    

    2023-02-13 12:59 回答
  • 你有两个字段,一个隐藏,而不是替换另一个.你有Foo.aBar.a 你覆盖方法改变Bar.a但你正在查找Foo.a

    2023-02-13 12:59 回答
  • 添加到Peter的答案:记住成员变量是are not多态的,所以它们不是overriden.
    f.a你仍然给你引用超类a(因为f声明的类型是Foo),而f.addFive()调用方法on Bar,(因为f运行时类型是Bar);

    所以,例如

    Bar b = new Bar();
    Foo f = b;
    f.addFive();
    System.out.println(f.a); // prints 3
    System.out.println(b.a); // prints 13 as you have expected
    

    希望很清楚.

    2023-02-13 13:02 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有