栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java-多态的动态绑定机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java-多态的动态绑定机制

Java-多态的动态绑定机制

在通过学习完 Java 的封装、继承、多态 之后,我们通过下面一道例题来引出一个 Java 非常重要的一个机制:动态绑定机制。

习题
class A { // 父类
	public int i = 10;
	public int sum() {
		return getI() + 10;
	}
	public int sum1() {
		return i + 10;
	}
	public int getI() {
		return i;
	}
}

class B extends A { // 子类
	public int i = 20;
	public int sum() {
		return i + 20;
	}
	public int getI() {
		return i;
	}
	public int sum1() {
		reutnr i + 10;
	}
}

public class Main {
	public static void main(String[] args) {
		// a 的编译类型是 A,运行类型是 B
		A a = new B(); 	// 类的多态(向上转型)
		System.out.println(a.sum()); 	// ?
		System.out.println(a.sum1());   // ?
	}
}
动态绑定机制的规则:
  1. 当调用对象方法的时候,该方法会和对象的内存地址 / 运行类型绑定;
  2. 当调用对象属性时,属性没有动态绑定机制,属性在哪里声明,就哪里使用(就近原则)。
习题 分析

a.sum() 变量 a a a 的编译类型是 A A A, 运行类型是 B B B,根据动态绑定机制,实例 a a a 调用方法时的首先在运行类型 B B B 中找,而此时 B B B 中有 s u m ( ) sum() sum() 方法,因此此时调用的是 B B B 中的 s u m ( ) sum() sum() 方法;而 B B B 中 s u m ( ) sum() sum() 定义为 return i + 20,因为属性是没有动态绑定机制的,因此 i i i 在 B B B 中声明什么就是什么,跟 A A A 中定义的 i i i 无关, 因此返回的是 20 + 20 = 40
即 System.out.println(a.sum()); // 40

a.sum1() 中 s u m 1 ( ) sum1() sum1() 调用的是运行类型 B B B 中定义的, i i i 没有动态绑定机制,由就近原则 i = 20 i = 20 i=20,因此 System.out.println(a.sum1()); // 30

变题1
class A { // 父类
	public int i = 10;
	public int sum() {
		return getI() + 10;
	}
	public int sum1() {
		return i + 10;
	}
	public int getI() {
		return i;
	}
}

class B extends A { // 子类
	public int i = 20;
	//  public int sum() {
	//     return i + 20;
	//  }
	public int getI() {
		return i;
	}
	public int sum1() {
		reutnr i + 10;
	}
}

public class Main {
	public static void main(String[] args) {
		// a 的编译类型是 A,运行类型是 B
		A a = new B(); 	// 类的多态(向上转型)
		System.out.println(a.sum()); 	// ?
	}
}
变题1 分析

a.sum() 中,因为 a a a 运行类型是 B B B,所以优先去 B B B 中找 s u m ( ) sum() sum(),但是 B B B 中没有定义 s u m ( ) sum() sum(),因此由继承机制再从 B B B 的父类 A A A 中找是否有 s u m ( ) sum() sum() 方法,而 A A A 中定义了 s u m ( ) sum() sum() 方法,因此 a.sum() 使用的是 A A A 中定义的 s u m ( ) sum() sum() 方法;而 A A A 的 s u m ( ) sum() sum() 方法中还调用了 g e t I ( ) getI() getI() 方法,因为运行类型是 B B B,方法具有动态绑定机制,依然去 B B B 中找是否有 g e t I ( ) getI() getI() 方法,因此使用的是 B B B 类中的 g e t I ( ) getI() getI() 方法; B B B 类 g e t I ( ) getI() getI() 方法中返回了 i i i,因为变量没有动态绑定机制,由就近原则知 i = 20 i=20 i=20,因此最终的结果为20 + 10 = 30

小结:这个变题告诉我们,尽管可能发生函数的嵌套调用,执行嵌套的函数时依然还是先去运行类型中去找。

变题2
class A { // 父类
	public int i = 10;
	public int sum() {
		return getI() + 10;
	}
	public int sum1() {
		return i + 10;
	}
	public int getI() {
		return i;
	}
}

class B extends A { // 子类
	public int i = 20;
	//  public int sum() {
	//     return i + 20;
	//  }
	public int getI() {
		return i;
	}
	//  public int sum1() {
	//  	reutnr i + 10;
	//  }
}

public class Main {
	public static void main(String[] args) {
		// a 的编译类型是 A,运行类型是 B
		A a = new B(); 	// 类的多态(向上转型)
		System.out.println(a.sum1()); 	// ?
	}
}
变题2 分析

a.sum1() 中,因为 a a a 的运行类型是 B B B,因此先去 B B B 中找 s u m 1 ( ) sum1() sum1(),而 B B B 中没有定义 s u m 1 ( ) sum1() sum1(),因此去 B B B 的父类 A A A 中找 s u m 1 ( ) sum1() sum1(),因为 A A A 中定义了 s u m 1 ( ) sum1() sum1(),因此使用的 s u m 1 ( ) sum1() sum1() 来自 A A A; A A A 中的 s u m 1 ( ) sum1() sum1() 返回的是 i + 10 i + 10 i+10,由变量没有动态绑定机制、仅仅服从就近原则,得出 i = 10 i=10 i=10,因此返回的是 10 + 10 = 20

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/434274.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号