此次所有的讨论都是子类赋值给父类时出现的情况。
静态绑定:
在程序执行前方法已经被绑定,此时是由编译器或者其他链接程序实现
1 Java中的方法只有final ,static,private,构造方法是静态绑定
2 所有的属性都是静态绑定。
动态绑定:
运行时根据具体对象的类型进行绑定
父类子类
子类赋值给父类时,
1 父类中有声明的方法才可以调用,父类中未声明,子类中声明无法调用子类方法。(规定)
2 父类子类都声明的方法,在父类中无privatestatic final修饰或者不是父类的构造函数,调用子类的方法。(无修饰,调子类)(动态绑定)
3 父类子类都声明的方法,在父类中被privatestatic final修饰或者是父类的构造函数,则调用父类的方法。(有修饰,调父类)(静态绑定)
4 父类子类都声明的属性,调用父类的属性。(全声明,调父类)(静态绑定)
5 父类中声明的属性,子类未声明,则调用父类的属性。
子类赋值给父类时
对于方法来说,只要有子类,就要用子类的,子类没有时,就直接调用父类的方法。
父类animal:
package Com; public class Animal { public String name; // 父类子类中同时声明,调用父类(静态绑定) public String Color; // 构造器 静态绑定 public Animal() { this("Animal","未赋色"); } public Animal(String name,String Color) { this.name=name; this.Color=Color; System.out.println("Animal.... 构造器"); } // static 修饰 静态绑定 public static int age;// 属于类(静态绑定) public static void agefuc() // 静态方法(静态绑定) { System.out.println("类的年龄是"+age); } //final 修饰 静态绑定 public final int gogo=111;// 常量 不能更改 属于父类 public final void go() // 常量函数 意味着该方法不能被重写 { System.out.println("常量函数!!!"); } // private 只能类中调用 静态绑定 private int pp=123; private int getPP() { return 222; } //普通方法 子类赋值给父类时,调用的是子类的方法 public void howl() { System.out.println(name+" .....xxxxx....."); } public void showColor() { System.out.println(Color+"....父类...."); } //子类中无此方法,则调用直接调用父类方法 public void msg() { } }
package Com; public class Cat extends Animal{ public String name; // 父类中也有name属性,但由于是静态绑定,所以调用子类howl,无法得到name的值,输出为null // Cat子类中没有Color属性,直接从父类继承过来。 // 构造器为静态绑定,子类new一个新的对象赋值给父类时,实际调用的是父类的构造器(String name,String Color) 而不是Cat(String name,String Color) public Cat() { super(); // 可省略 } public Cat(String name,String Color) { this.name=name; this.Color=Color; System.out.println("Cat.....构造器"); } public void howl() { System.out.println(name+"..... miaomiao!!!"); } public void showColor() { System.out.println(Color+"....子类...."); } }
Main:
package Com; public class main { public static void main(String args[]) { //此次所有的讨论都是子类赋值给父类时出现的情况。 Animal a = new Cat(); // 编译期时,a被认为是Animal类型的,运行期时,a被认为是Cat(); a.name="xiaomao"; a.Color="白色"; //(动态绑定) 调用子类的方法时,子类属性值为最高优先级的属性值(本类属性优先级>父类属性优先级) a.howl(); // 调用的是子类的方法,但由于父类子类中都有name属性,实际调用父类属性(静态绑定),子类不赋值,子类输出自己的name属性时,为NULL a.showColor(); //调用的子类的方法,只有在父类中声明color,子类输出父类的color 为”白色“。 // 常量方法 (静态绑定) a.go(); Animal.age=12;// 属于类,不需要new对象,可直接调用。(静态绑定) Animal.agefuc(); } }
name属性为父类子类都声明的,调用的是父类的属性(静态绑定),子类的方法 (动态绑定)
color属性是父类声明的,子类调用时直接接收父类的“白色”值
常量函数为静态绑定
static 修饰的是静态绑定
小结:
静态绑定和动态绑定的实质就是子类赋值给父类时,谁被调用的情况。静态绑定是在链接时被调用,而动态绑定是程序跑起来时被调用。