Java中静态绑定与动态绑定详解

这里有2个类

父类 Father

public class Father {

    public static int fa =1; 
    private static int fb =2; 
    protected static int fc =3; 
    static int fd =4; 

    public int a = 1;
    private int  b = 2;
    protected int c = 3;
    int d = 4;

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }


    public Father() {
        System.out.println("i am father constructor");
    }


    public void haha(){
        System.out.println("father haha");
    }


    public static void hehe (){
        System.out.println("father hehe");
    }

}

子类 Son

public class Son extends Father {
    public static int fa =5; 
    private static int fb =6; 
    protected static int fc =7; 
    static int fd =8; 

    public int a = 5;
    private int  b = 6;
    protected int c = 7;
    int d = 8;



    public Son(int a) {
        this.a = a;
        System.out.println("defined son's constructor");
    }


    public Son() {
        //会默认执行父类的无参构造器
        System.out.println("son's constructor");
    }


    @Override
    public void haha() {
        System.out.println("son haha");
    }

    public static void hehe (){
        System.out.println("son hehe");
    }


    public void getFatherFiled(){
        System.out.println("---------------获取Father的静态字段---------------");
        System.out.println("Father static int1 " + super.fa);
        System.out.println("Father static int2  =====> 这里 为Father's private static int fb" );
        System.out.println("Father static int3 " `这里写代码片`+ super.fc);
        System.out.println("Father static int4  " + super.fd);
        System.out.println("---------------获取Son的静态字段---------------");
        System.out.println("Son static int1 " + fa);
        System.out.println("Son static int2 " + fb);
        System.out.println("Son static int3 " + fc);
        System.out.println("Son static int4 " + fd);
        System.out.println("---------------获取Father的非静态字段---------------");
        System.out.println("Father  int1 " + super.a);
        System.out.println("Father  int2 " + super.getB());
        System.out.println("Father  int3 " + super.c);
        System.out.println("Father  int4 " + super.d);
        System.out.println("---------------获取Son的非静态字段---------------");
        System.out.println("Son  int1 " + a);
        System.out.println("Son  int2 " + b);
        System.out.println("Son  int3 " + c);
        System.out.println("Son  int4 " + d);

        System.out.println("----------------------调用父类的静态方法-------------------------");
        super.hehe();
        System.out.println("----------------------调用父类的非静态方法-------------------------");
        super.haha();
        System.out.println("----------------------调用自己的静态方法-------------------------");
        hehe();//this.hehe();会有黄线警告 静态方法 不推荐这种调用
        System.out.println("----------------------调用自己的非静态方法-------------------------");
        haha();//this.haha()
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        Father fa = new Son();//会默认执行父类的无参构造器
        //Father fa = new Son(1);会默认执行父类的无参构造器

        //静态绑定 输出实例变量
        System.out.println("-----------输出实例变量-----------");
        System.out.println(fa.a);
        System.out.println(fa.getB());
        System.out.println(fa.c);
        System.out.println(fa.d);
        System.out.println("-------------静态变量--------------");
        //输出静态字段
        System.out.println(fa.fa);
        System.out.println(fa.fc);
        System.out.println(fa.fd);

        //动态绑定  对于非静态方法 
        fa.haha();
        //这里相当于调用了Father.hehe(); 
        fa.hehe();//因此输出为father hehe 而不是son hehe;

        System.out.println("------------son获取所有父类以及自己的变量------------");
        ((Son)fa).getFatherFiled();

    }
}

结果:

i am father constructor
son's constructor
-----------输出实例变量-----------
1
2
3
4
-------------静态变量--------------
1
3
4
son haha
father hehe
------------son获取所有父类以及自己的变量------------
---------------获取Father的静态字段---------------
Father static int1 1
Father static int2  =====> 这里 为Father's private static int fb
Father static int3 3
Father static int4  4
---------------获取Son的静态字段---------------
Son static int1 5
Son static int2 6
Son static int3 7
Son static int4 8
---------------获取Father的非静态字段---------------
Father  int1 1
Father  int2 2
Father  int3 3
Father  int4 4
---------------获取Son的非静态字段---------------
Son  int1 5
Son  int2 6
Son  int3 7
Son  int4 8
----------------------调用父类的静态方法-------------------------
father hehe
----------------------调用父类的非静态方法-------------------------
father haha
----------------------调用自己的静态方法-------------------------
son hehe
----------------------调用自己的非静态方法-------------------------
son haha

结论:
1.子类继承父类 会继承父类中的所有(包括父类的静态方法,静态变量,实例方法,实例变量(非静态)) 即:在子类进行实例化的时候 会有一份父类的引用,这里为super。可以在子类中使用获取父类中的方法和字段。
2.子类可以直接访问父类中的非private 字段和方法 (包括静态和非静态)
3.子类可以重载这些方法 包括父类中的构造方法,但是覆盖的构造方法依然会执行父类的无参构造器(默认)
4.静态绑定:在构造一个子类的实例并向上转型为其父类的时候,利用父类的引用获取的字段 是 父类中的字段 (静态和非静态)。
5.但是调用的方法(这里要强调是实例方法) 是子类中覆盖的方法! (若用父类的引用去调用静态方法 那么还是调用了原来父类中的方法。(当然不推荐这么做 你的编译器会有黄线,你应该用类.方法去调用你父类中的静态方法))。
上述 “但是调用的方法(这里要强调是实例方法) 是子类中覆盖的方法!”说的就是动态绑定。
6.最后子类除了可以覆盖父类中的原有方法 还可以自己添加额外的方法,但是如果向上转型为父类,其引用无法调用父类中没有的方法,在确保安全的情况下 可以向下转型,调用属于自己的方法。

        if(fa instanceof Son){
            ((Son)fa).getFatherFiled();
        }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值