今天在看秦小波的《设计模式之禅》的Visitor模式的时候,书中有提到:单分派(single dispatch)和双分派(double dispatch,多分派(multi-dispatch)的一种),以及动态绑定和静态绑定和重载(overload)、覆盖(override)之关联,在网上找了下资料:
发现以下几个文章解释的比较好:(其中错误的地方有改动)
一、【转自】http://hi.baidu.com/haoyan665/blog/item/239c0be775aebe2ab9382090.html
变量被声明时的类型叫做变量的静态类型(Static Type) 又叫明显类型(Apparent Type)。
变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type)。
如:
Horse wh = new WhiteHorse();
Horse 为静态类型、WhiteHorse 为实际类型。
根据对象的类型而对方法进行的选择,就是分派(Dispatch)。
分派分静态分派和动态分派。
静态分派(Static Dispatch) 发生在编译时期,分派根据静态类型信息发生。
方法重载(Overload)就是静态分派。
动态分派(Dynamic Dispatch) 发生在运行时期,动态分派动态地置换掉某个方法。面向对象
的语言利用动态分派来实现方法置换产生的多态性。
静态分派实例:
public class Mozi{
public void ride(Horse h){
System.out.println("Riding a horse");
}
public void ride(WhiteHorse h){
System.out.println("Riding a white horse");
}
public void ride(BlackHorse h){
System.out.println("Riding a black horse");
}
public static void main(String[] args) {
Horse wh = new WhiteHorse();
Horse bh = new BlackHorse();
Mozi mozi = new Mozi();
mozi.ride(wh);
mozi.ride(bh);
}
}
运行时程序打印出相同的两行“Riding a horse”。也就是都调用了方法ride(Horse h)。两次对ride()方法的调用传入的是不同的参量,也就是wh和bh。它们虽然具有不同的真实类型,但是它们的静态类型都是一样的,均是Horse 类型。
重载方法的分派是根据静态类型进行的。这个分派过程在编译时期就完成了。
动态分派实例:
Java通过方法的置换(Overriding)支持动态分派。
String s1 = "ab";
Object o = s1 +"c";
String s = "abc";
boolean b = o.equals(s);
变量s1 和s的静态类型和真实类型都是String,而o的静态类型是Object,真实类型则是Object类型的一个子类型(String)。
如果上面最后一行的equals()方法调用的是String类的equals()方法,那么上面代码检查的就是o的值是否等于字符串“abc”;相反,如果上面的equals()方法调用的是Object类的equals()方法,那么松检查的就是o所指的对象和s1所指的对象是不是同一个对象。
问题的核心是Java编译器在编译时期并不总是知道哪一些代码会被执行。因为种种原因编译器仅仅知道对象的静态类型,而不知道对象的真实类型;而方法的调用则是根据对象的真实类型,而不是静态类型。仍以上面的代码为例。变量o指向一个类型为String的对象。这个String对象的值是“abc”。所上面最后一行的equals方法调用的是String类的equals()方法。所上面的最后的b值为true。
分派类型
一个方法所属的对象叫做方法的接收者,方法的接收者与方法的参量统称做方法的宗量。
根据分派可以基于多少种宗量,可以将面向对象的语言划分为单分派语言和多分派语言.单元分派语言根据一个宗量的类型进行对方法的选择,多分派语言根据多于一个的宗量的类型对方法进行选择。
在一个支持动态单分派的语言里面,有两个条件决定了一个请求会调用哪一个操作:一是请求的名字,二是接收者的真实类型。单分派限制了方法的选择过程,使得只有一个宗量可以被考虑到,这个宗量通常就是方法的接收者。在JAVA语言里面,如果一个操作是作用于某个类型不明的对象上面的。那么这个对象的真实类型测试仅会发生一次。这个就是动态的单分派的特征。
一言以蔽之,JAVA语言支持静态的多分派和动态的单分派。
实例:
public class Point{
int x,y;
void draw(){
}
void translate(int one){
}
void translate(int one,int two){
}
}
public class ColorPoint extends Point{
Color c;
void draw(){
}
}
public class Client{
private static Point p;
private static Point pc;
public static void main(String[] args) {
p = new Point();
pc = new ColorPoint();
//静态多分派
p.translate(5);
p.translate(1,2);
//动态单分派
p.draw();//调用Point.draw();
pc.draw();//调用ColorPoint.draw();
}
}
二、【转自】http://dreamstone.iteye.com/blog/77918
一,静态分派:
1,定义:发生在编译时期,分派根据静态类型信息发生,重载就是静态分派
2,什么是静态类型:变量被声明时的类型是静态类型
什么是动态类型:变量所引用的对象的真实类型
3,有两个类,BlackCat ,WhiteCat都继承自Cat
如下调用
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
public void feed(Cat cat){
System.out.println("feed cat");
}
public void feed(WhiteCat cat){
System.out.println("feed WhiteCat");
}
public void feed(BlackCat cat){
System.out.println("feed BlackCat");
}
public static void main(String[] args) {
Cat wc = new WhiteCat();
Cat bc = new BlackCat();
Person p = new Person();
p.feed(wc);
p.feed(bc);
}
}
运行结果是:
feed cat
feed cat
这样的结果是因为重载是静态分派,在编译器执行的,取决于变量的声明类型,因为wc ,bc都是Cat所以调用的都是feed(Cat cat)的函数.
二,动态分派
1,定义:发生在运行期,动态分派,动态的置换掉某个方法。
还是上边类似的例子:
class Cat{
public void eat(){
System.out.println("cat eat");
}
}
public class BlackCat extends Cat{
public void eat(){
System.out.println("black cat eat");
}
public static void main(String[] args){
Cat cat = new BlackCat();
cat.eat();
}
}
这个时候的结果是:
black cat eat
这样的结果是因为在执行期发生了向下转型,就是动态分派了。
三,单分派:
1,定义:根据一个宗量的类型进行方法的选择
四,多分派:
1,定义:根据多于一个宗量的类型对方法的选择
2,说明:多分派其实是一系列的单分派组成的,区别的地方就是这些但分派不能分割。
3,C++ ,Java都是动态单分派,静态多分派语言
多分派的语言有:CLOS Cecil
最后的部分:
看完本文,如果你对visitor模式有更多的兴趣,想了解更多请看如下几篇文章。
1,静态分派,动态分派,多分派,单分派 -------------- visitor模式准备(本文)
2,访问差异类型的集合类 ------------------------ visitor模式入门
3,visitor模式理论及学术概念------------------- visitor模式进一步
4,重载overloading和覆写overriding哪个更早执行-- visitor帮助篇
虽然排列顺序是1,2,3,4但是我个人建议的学习方式是2,1,3,4因为这个顺序更方便一般人理解
分享到:
相关推荐
总的来说,动态分派是Java中多态性的核心,允许我们编写更抽象和可扩展的代码。`dynamicDispatch`示例程序是一个很好的学习工具,可以帮助我们更好地理解和应用这一概念。通过分析和运行这个程序,开发者可以深化对...
### Java多线程并发实战知识点解析 #### 一、引言 在计算机科学领域,**多线程**和**并发**技术是现代软件开发中不可或缺的一部分。随着处理器核心数量的增加,利用多线程和并发可以显著提高应用程序的性能和响应...
本方法是用axis1.4技术,实现java客户端调用webservice。已经可实现过可行的,如果不行可加我QQ号302633进行详细解析。
这些组合形成了不同的分派策略,例如静态单分派、静态多分派、动态单分派和动态多分派。 在静态分派中,如Java的多态方法重载,调用版本在编译时就已经确定。而在动态分派中,如方法覆写,调用版本取决于运行时对象...
这个版本相较于早期版本有很多改进,例如在Swing组件的使用上提供了更多的稳定性和更丰富的组件库。 Java Swing编程实验报告可能涉及以下知识点: - Swing组件的使用和布局管理器:了解如何将JButton, JLabel, ...
Java 中的分派可以分为以下几种: *静态分派(Static Dispatch):根据静态类型进行分派。 * 虚分派(Virtual Dispatch):根据虚方法表进行分派。 虚方法表 Java 中的虚方法表用于存储虚方法的信息,包括方法的...
Java虚拟机的多线程实现是通过线程轮番切换并分派处理器执行时刻的方法来实现的。Java虚拟机的垃圾收集器(Garbage Collector)负责收集垃圾对象,以释放内存空间。垃圾收集器的算法包括引用计数算法和根搜索算法。...
理解它们的概念、应用场景,以及静态多分派和动态单分派、重载、接口多实现、基类单继承、抽象类、接口、多态(方法覆盖和接口回调)等概念,是成为合格Java开发者的必备条件。 最后,静态属性(Static)是Java中的...
分派还可以根据宗量数(影响方法选择的因素)进一步划分为静态单分派、静态多分派、动态单分派和动态多分派。静态分派只考虑静态类型,而动态分派则依赖于实际类型。Java中主要是静态分派和动态分派,但不支持静态多...
本文档详细列举了Java并发领域面试中常见的问题,以下是对这些问题及答案的解析。 1.1 多线程和并发问题。并发是指两个或多个事件在同一时间间隔内发生,多线程是实现并发的一种方式,可以通过创建多个线程,让它们...
在Java中,线程使得程序能够同时执行多个任务,极大地提高了程序的效率和响应速度。 #### 线程与进程的关系 在操作系统层面,进程是资源分配和调度的基本单位,而线程则是CPU调度和分派的基本单位。一个进程可以...
- **词法分析器**:解析源代码为tokens。 - **语法分析器**:构建抽象语法树。 - **语义分析器**:添加注解并检查语义错误。 - **字节码生成器**:生成字节码。 - **JVM**:包括字节码解释器和即时编译器(JIT)...
3. **Handlers**:处理IO事件的回调函数,执行实际的业务逻辑,如解析请求、处理服务和编码响应。 4. **Dispatcher**:Reactor本身,负责根据发生的事件将工作分派到对应的Handler。 在Java中,基本的Reactor模式...
Java中的方法重载(Overloading)属于静态多分派,而方法重写(Overriding)在早期JVM中是动态单分派,但JDK7开始支持动态多分派以增强对动态语言的支持。 JVM执行引擎还可以进行优化,如使用虚表(vtable)实现...
这份“大厂真题之京东-Java实习生.pdf”涵盖了多个核心知识点,包括垃圾回收机制、字符编码、代理模式、异常处理以及解析与分派。 首先,垃圾回收机制是Java内存管理的关键部分。它主要通过可达性分析算法来判断...
本文旨在深入解析Java线程的理论基础、应用场景及其实现机制,帮助Java开发者更好地理解和运用这一关键特性。 #### 二、Java线程基础知识 **1. 什么是线程?** 线程是操作系统能够进行运算调度的最小单位,它被...
总结来说,Java中的多态性主要通过方法的重载和重写,以及JVM的动态分派机制来实现。理解这些原理有助于深入掌握Java的面向对象特性和虚拟机的运作机制。在编程实践中,利用多态可以编写出更加灵活、可扩展的代码。
从给定的文件信息来看,主要内容聚焦于Java中多线程任务分配的策略与实践,尤其是在处理大量任务时如何高效地将其分派给多个线程进行并行处理。以下是对这一知识点的深入解析: ### 多线程任务分配策略 在Java编程...
5. **解析与分派**:解析是编译期间完成的过程,确定方法调用的具体实现,将符号引用转换为直接引用。而分派则是在运行时根据实际参数类型决定调用哪个方法,分为静态分派(编译期确定,基于类型)和动态分派(运行...