此次所有的讨论都是子类赋值给父类时出现的情况。
静态绑定:
在程序执行前方法已经被绑定,此时是由编译器或者其他链接程序实现
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()
{
}
}
子类Cat:
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 修饰的是静态绑定
小结:
静态绑定和动态绑定的实质就是子类赋值给父类时,谁被调用的情况。静态绑定是在链接时被调用,而动态绑定是程序跑起来时被调用。