关于java中向上造型访问成员变量和成员方法的一些细节

public class TestFoo{
    public static void main(String[] args) {
        Fo f = new Bar();
        f.addFive();
        System.out.println(f.a);
        //f.print();
        //System.out.println(f.b);
        //System.out.println(f.getA());
    }
}
class Fo{
    public int a;
    public Fo(){
        a = 3;
    }
    public void print(){
        System.out.println("这里是父类!");
    }
    public void addFive(){
        a += 5;
    }
}
class Bar extends Fo{
    public int a;
    public int b;
    public Bar(){
        a = 8;
    }
    public void addFive(){
        this.a += 5;
    }
    public int getA(){
        return this.a;
    }
}

代码的输出结果为3。
在这里插入图片描述
相信很多学到Java对象的读者会有这样的疑问:为什么我在子类中重写了方法,调用了重写方法,经过方法体“改造”所得到的成员变量输出结果却不是我想要的?
这里就涉及到了java面向对象程序设计的四大特征之一的多态性

  • 父类和子类的成员变量是同时存在的,即便甚至是同名。
  • 在子类中看到的是子类的变量(也包括从父类继承的除私有之外的成员变量,虽然被隐藏了),在父类中看到的是父类中的变量。
  • 各成员变量互不影响,而同名的成员方法则是实实在在的覆盖(重写)

在此例中 Fo f = new Bar(); 父类引用指向子类对象就是多态中的向上造型,父类引用只能调用父类的方法。
在这里插入图片描述我们可以看到父类的方法可以被调用(包括父类特有的方法),但是子类特有的方法却无法调用。

而其中如果此方法被它指向的子类对象进行了重写,那么调用的方法就是子类重写后的形式,这也是多态的表现(动态绑定))。接下来我会利用DeBug将该问题和开篇所讲的成员变量一同述说。
在这里插入图片描述可以看到先是调用父类的构造方法对成员变量进行初始化

在这里插入图片描述随后是在子类的构造方法中对子类的成员变量进行初始化(注意这里的同名成员变量a是子类自己的)

在这里插入图片描述到了这一步确实也是验证了上文所说的调用子类的同名重写方法,但注意这里同样也是对子类自己的同名成员变量a进行重赋值,而不是对父类的成员变量进行覆盖重写。

在这里插入图片描述当方法退出方法栈后,返回主方法后,我们可以看到图中第一行和第三行有标注,f对象的引用地址都是同一地址,因为始终是父类引用。到这里结果自然而然显现出开头所说的输出结果为3.
访问同名成员变量和访问同名成员方法是不同, 因为java中,向上造型呈现的多态性仅仅针对成员方法,成员变量不具有多态性。

另外我们还可以看到,父类引用对于子类特有的成员变量也是不允许访问的。在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值