java单双派机制理解
引言:Java是一个支持双分派的单分派语言
知道java是支持后期动态绑定,也知道访问者模式,但是两者之间的关系,还真不知道,况且在这之间还有一个静态绑定。
1.动态绑定
class Father {
    public void method(){
        System.out.println("This is Father's method");
    }
}
class Son1 extends Father{
    public void method(){
        System.out.println("This is Son1's method");
    }
}
class Son2 extends Father{
    public void method(){
        System.out.println("This is Son2's method");
    }
}
public class Test {
    public static void main(String[] args){
        Father s1 = new Son1();
        s1.method();
        Father s2 = new Son2();
        s2.method();
    }
}
打印结果:
This is Son1′s method
This is Son2′s method
使用过java的,这上面的结果,都会不屑一顾。那么在看下面一个例子,反正我自己是傻眼了
2.静态绑定
class Father {
}
class Son1 extends Father {
}
class Son2 extends Father {
}
class Execute {
    public void method(Father father) {
        System.out.println("This is Father's method");
    }
    public void method(Son1 son) {
        System.out.println("This is Son1's method");
    }
    public void method(Son2 son) {
        System.out.println("This is Son2's method");
    }
}
很神奇的发现,打印了结果是这样
This is Father's method
This is Father's method
This is Father's method
对于重载,只是在编译的时候,就已经决定了。是根据申明对象来选择具体调用哪个重载的方法,因此才会全部调用父类的方法
当然,我们可以通过instanceof关键字来处理,但是这样,如果有较多子类,这样逻辑判断起来就会很别扭,而且没增加一个子类,都需要新增一个if else 否则,代码就会出现问题
这样,就明白了,引言说的,java是单派语言。那么如何理解,支持双派呢?答案在于java可以通过访问者模式来实现双派机制
首先,看下一个简单的例子
class Visitor_A {
    public void method1() {
        System.out.println("Visitor_A dosomething");
    }
    public void method2(Visitor_B b) {
        b.callA(this);
    }
}
class Visitor_B {
    public void callA(Visitor_A a) {
        a.method1();
    }
}
   public static void main(String[] args) {
        Visitor_A visitor_a = new Visitor_A();
        Visitor_B visitor_B = new Visitor_B();
        visitor_a.method1();
        visitor_B.callA(visitor_a);
}
上面,就是访问者模式的最基础形式,通过观察者B来访问A的接口,来实现双派能力,其实也是使用本质也是依赖了java的后期动态绑定机制能力
class Father {
    public void accept(Execute exe){
        exe.method(this);
    }
}
class Son1 extends Father{
    public void accept(Execute exe){
        exe.method(this);
    }
}
class Son2 extends Father{
    public void accept(Execute exe){
        exe.method(this);
    }
}
class Execute {
    public void method(Father father){
        System.out.println("This is Father's method");
    }
    public void method(Son1 son){
        System.out.println("This is Son1's method");
    }
    public void method(Son2 son){
        System.out.println("This is Son2's method");
    }
}
public class Test {
    public static void main(String[] args){
        Father father = new Father();
        Father s1 = new Son1();
        Father s2 = new Son2();
        Execute exe = new Execute();
        father.accept(exe);
        s1.accept(exe);
        s2.accept(exe);
    }
}
想了解更多理论讨论,可以移步这里:http://www.iteye.com/topic/1130764
java单双派机制理解的更多相关文章
- Java ClassLoader加载机制理解 实际例子
		
针对 Java ClassLoader加载机制理解, 做了个如何自定制简单的ClassLoader,并成功加载指定的类. 不废话,直接上代码. package com.chq.study.cl; im ...
 - Java ClassLoader加载机制理解
		
今天看到了一篇介绍Java ClassLoader加载机器的文章, 才发觉一直来自己的肤浅, 好好地给补了一课, 不得不存档! 原文地址: http://www.blogjava.net/lhulcn ...
 - Java——单双引号的区别
		
单引号: 单引号包括的是单个字符,表示的是char类型.例如: char a='1' 双引号: 双引号可以包括0个或者多个字符,表示的是String类型. 例如: String s="ab ...
 - java单双引号转义问题
		
JavaScript代码:var str = '<a href="javascript:;" onclick="visaDetail(\'1\',' + value ...
 - java——String、StringBuffer、StringBuilder、包装类、单双引号
		
String: String是一个特殊的类,被定义为final类型,为字符串常量,同样的字符串在常量池中不能重复. 但是由于使用关键字new创建新的字符串,java会在对中分配新的空间,这样即使字符串 ...
 - 【Java】深入理解Java中的spi机制
		
深入理解Java中的spi机制 SPI全名为Service Provider Interface是JDK内置的一种服务提供发现机制,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用 ...
 - 深入理解Java中的反射机制
		
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...
 - Java单例和多例
		
背景:最近在学习韩老师的笔记时候发现不是很了解单例和多例,于是通过网上查找资料的方式去学习. 设计模式:最佳的实践,是软件开发人员在软件开发过程中面临一般解决方案,也就是开发的经验总结. 单例模式(S ...
 - java单例-积木系列
		
一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...
 
随机推荐
- @SuppressLint("NewApi")和@TargetApi()的区别
			
在Android代码中,我们有时会使用比我们在AndroidManifest中设置的android:minSdkVersion版本更高的方法,此时编译器会提示警告, 解决方法是在方法上加上@Suppr ...
 - URAL 1224. Spiral  (规律)
			
1224. Spiral Time limit: 1.0 second Memory limit: 64 MB A brand new sapper robot is able to neutrali ...
 - jstl函数的使用
			
1.fn:contains()和fn:containsIgnoreCase() fn:contains()函数用于确定一个字符串是否包含指定的子串. fn:containsIgnoreCase()函数 ...
 - 学习 Linux,302(混合环境): Samba 角色
			
http://www.ibm.com/developerworks/cn/linux/l-lpic3-310-2/ 概述 在本文中,了解下列概念: Samba 安全模式 核心 Samba 守护程序的角 ...
 - 1050: 贝贝的ISBN号码(isbn)
			
#include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...
 - POSTGRESQL 查看用户使用情况以及杀掉相应的进程
			
一.查看哪些用户在链接数据库 select * from pg_stat_activity ; 这里的pg_stat_activity其实是一个视图,它的定义可以在postgres这个数据库里面的视图 ...
 - Maven依赖的Scope去除部署不需要的jar 包(打包)
			
<dependency> < groupId>javax.servlet</groupId> < artifactId>jsp-api</arti ...
 - 定制保存top输出信息的格式详解
			
top命令的重要性和使用方法不多说了,这里终点讨论如何保存top命令的输出信息. 保存top命令的输出到一个文件的方法是:top -n1b > topinfo.txt,这没什么好奇的,但 ...
 - OpenCV实现任意大小图片的合并(转)
			
OpenCV实现图像合并主要有两种方法 方法一:使用Mat.push_back方法将列数相同的图像加到最后一行 方法二: 主要思路是将图像拷贝到待合并图像的感兴趣区域 (1)新建一个要合并的图像(容器 ...
 - Fiddler Web Debugger简单调试头部参数
			
POST接口时头部参数如下: User-Agent: Fiddler Host: api.***.com Content-Length: Content-Type: application/json ...