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

来源:互联网 发布:淘宝双十一晚会2017 编辑:程序博客网 时间:2024/05/29 07:38

这里有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 constructorson's constructor-----------输出实例变量-----------1234-------------静态变量--------------134son hahafather hehe------------son获取所有父类以及自己的变量---------------------------获取Father的静态字段---------------Father static int1 1Father static int2  =====> 这里 为Father's private static int fbFather static int3 3Father static int4  4---------------获取Son的静态字段---------------Son static int1 5Son static int2 6Son static int3 7Son static int4 8---------------获取Father的非静态字段---------------Father  int1 1Father  int2 2Father  int3 3Father  int4 4---------------获取Son的非静态字段---------------Son  int1 5Son  int2 6Son  int3 7Son  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();        }
原创粉丝点击