Java动态绑定机制
841字约3分钟
2024-12-02
Java动态绑定机制
当编译类型(父类)调用运行类型(子类)的时候,该编译类型会和该运行类型的内存地址进行绑定
属性没有动态绑定机制,所以在那里声明就使用那里的属性
方法才有动态绑定机制
// 父类 public class A { public int i = 10; public int sum() { // 优先调用 运行类型 中的getI() // 如果 运行类型 中没有 getI() 方法则在调用 编译类型 中的 getI() return getI() + 10; } public int getI() { // 属性没有动态绑定,所以那里声明就调用那里的属性 return i; } public int sum1() { return i + 10; } }
// 子类 public class B extends A { public int i = 20; public int sum() { return i + 20; } public int getI() { // 属性没有动态绑定,所以那里声明就调用那里的属性 // 先返回本类中的 i ,如果本类中没有 i 则返回父类中 i,都没有则会报错 return i; } public int sum1() { return i + 10; } }
// 运行 public class Test { public static void main(String[] args) { // 多态中的向上转型 A a = new B(); // 调用sum的时候会优先调用运行类型里面的sum // 如果运行类型里面的没有sum方法时则在去调用编译类型里面的sum System.out.println(a.sum()); // 40 System.out.println(a.sum1()); // 30 } }
多态数组
数组的定义类型为 编译类型 ,里面保存的实际元素类型为 运行类型
// 把 编译类型 创建成一个数组
// 然后在给每个元素创建一个 运行类型(这些运行类型都是Person的子类,动态分配)
Person[] p = new Person[5];
p[0] = new Person("张三 ",20);
p[1] = new Student("李四 ",18, "100");
p[2] = new Student("王麻子",18, "100");
p[3] = new Teacher("王老师", 30, 20000);
p[4] = new Teacher("李老师", 40, 25000);
多态参数
动态参数就是 方法中的形参列表里的参数可以为编译类型(父类类型),实参类型可以为运行类型(子类类型)
// 父类
public class Employee {
private String name;
private double wages;
public Employee(String name, double wages) {
this.name = name;
this.wages = wages;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getWages() {
return wages;
}
public void setWages(double wages) {
this.wages = wages;
}
public double getAnnual() {
return wages * 12;
}
}
// 子类
public class Manger extends Employee {
private double bonus;
public Manger(String name, double wages, double bonus) {
super(name, wages);
this.bonus = bonus;
}
public void work() {
System.out.println("经理:" + getName() + " 月薪:" + getWages() + " 年薪:" + getAnnual());
System.out.println(getName() + "正在工作。。。");
}
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
}
public class Ordinary extends Employee {
public Ordinary(String name, double wages) {
super(name, wages);
}
public void work() {
System.out.println("员工:" + getName() + " 月薪:" + getWages() + " 年薪:" + getAnnual());
System.out.println(getName() + "正在工作。。。");
}
@Override
public double getAnnual() {
return super.getAnnual();
}
}
// 运行
public class Test {
public static void main(String[] args) {
// 创建本类的对象,然后在调用本类对象中的方法
Test t = new Test();
Manger m = new Manger("李四", 30000, 5000);
Ordinary o = new Ordinary("张三", 20000);
// 将经理和普通员工传到 showEmpAnnual 方法中
t.showEmpAnnual(m);
t.showEmpAnnual(o);
// 调用运行类型中的方法,这里就是动态参数,实参为运行类型
t.testWork(m);
t.testWork(o);
}
public void showEmpAnnual(Employee e) {
// 输出所对应的年薪
System.out.println(e.getAnnual());
}
// 形参为编译类型
public void testWork(Employee e) {
// 工作状态
if (e instanceof Manger) {
// 将父类强转为子类,然后在调用子类中的方法
((Manger) e).work();
} else if (e instanceof Ordinary) {
((Ordinary) e).work();
}
}
}