当前位置:编程学习 > JAVA >>

《JAVA与模式》第24天—访问者模式

访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

分派的概念

  变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type);而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type)。比如

[java]
List list = null; 
list = new ArrayList(); 
List list = null;
list = new ArrayList();
 

 

  声明了一个变量list,它的静态类型(也叫明显类型)是List,而它的实际类型是ArrayList。

  根据对象的类型而对方法进行的选择,就是分派(Dispatch),分派(Dispatch)又分为两种,即静态分派和动态分派。

  静态分派(Static Dispatch)发生在编译时期,分派根据静态类型信息发生。静态分派对于我们来说并不陌生,方法重载就是静态分派。

  动态分派(Dynamic Dispatch)发生在运行时期,动态分派动态地置换掉某个方法。

 静态分派
  Java通过方法重载支持静态分派。用墨子骑马的故事作为例子,墨子可以骑白马或者黑马。墨子与白马、黑马和马的类图如下所示:

 

\

 

  在这个系统中,墨子由Mozi类代表

[java] 
package com.bankht.Visitor; 
 
/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:41:24
 * 
 * @类说明 :在这个系统中,墨子由Mozi类代表
 */ 
public class Mozi { 
 
    public void ride(Horse h) { 
        System.out.println("骑马"); 
    } 
 
    public void ride(WhiteHorse wh) { 
        System.out.println("骑白马"); 
    } 
 
    public void ride(BlackHorse bh) { 
        System.out.println("骑黑马"); 
    } 
 
    public static void main(String[] args) { 
        Horse wh = new WhiteHorse(); 
        Horse bh = new BlackHorse(); 
        Mozi mozi = new Mozi(); 
        mozi.ride(wh); 
        mozi.ride(bh); 
    } 
 

package com.bankht.Visitor;

/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:41:24
 *
 * @类说明 :在这个系统中,墨子由Mozi类代表
 */
public class Mozi {

 public void ride(Horse h) {
  System.out.println("骑马");
 }

 public void ride(WhiteHorse wh) {
  System.out.println("骑白马");
 }

 public void ride(BlackHorse bh) {
  System.out.println("骑黑马");
 }

 public static void main(String[] args) {
  Horse wh = new WhiteHorse();
  Horse bh = new BlackHorse();
  Mozi mozi = new Mozi();
  mozi.ride(wh);
  mozi.ride(bh);
 }

}

 

  显然,Mozi类的ride()方法是由三个方法重载而成的。这三个方法分别接受马(Horse)、白马(WhiteHorse)、黑马(BlackHorse)等类型的参数。

  那么在运行时,程序会打印出什么结果呢?结果是程序会打印出相同的两行“骑马”。换言之,墨子发现他所骑的都是马。

  为什么呢?两次对ride()方法的调用传入的是不同的参数,也就是wh和bh。它们虽然具有不同的真实类型,但是它们的静态类型都是一样的,均是Horse类型。

  重载方法的分派是根据静态类型进行的,这个分派过程在编译时期就完成了。

 动态分派
  Java通过方法的重写支持动态分派。用马吃草的故事作为例子,代码如下所示:

[java] 
package com.bankht.Visitor; 
 
/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:41:46
 * 
 * @类说明 :Java通过方法的重写支持动态分派。用马吃草的故事作为例子
 */ 
public class Horse { 
 
    public void eat() { 
        System.out.println("马吃草"); 
    } 
 

package com.bankht.Visitor;

/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:41:46
 *
 * @类说明 :Java通过方法的重写支持动态分派。用马吃草的故事作为例子
 */
public class Horse {

 public void eat() {
  System.out.println("马吃草");
 }

}
 

 

[java]
package com.bankht.Visitor; 
 
/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:43:15
 * 
 * @类说明 :
 */ 
public class WhiteHorse extends Horse { 
 
    @Override 
    public void eat() { 
        System.out.println("白马吃草"); 
    } 

package com.bankht.Visitor;

/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:43:15
 *
 * @类说明 :
 */
public class WhiteHorse extends Horse {

 @Override
 public void eat() {
  System.out.println("白马吃草");
 }
}
 

 

[java] 
package com.bankht.Visitor; 
 
/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:42:08
 * 
 * @类说明 :
 */ 
public class BlackHorse extends Horse { 
 
    @Override 
    public void eat() { 
        System.out.println("黑马吃草"); 
    } 

package com.bankht.Visitor;

/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:42:08
 *
 * @类说明 :
 */
public class BlackHorse extends Horse {

 @Override
 public void eat() {
  System.out.println("黑马吃草");
 }
}
 

 

[java]
package com.bankht.Visitor; 
 
/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:42:34
 * 
 * @类说明 :
 */ 
public class Client { 
 
    public static void main(String[] args) { 
        Horse h = new BlackHorse(); 
        h.eat(); 
    } 
 

package com.bankht.Visitor;

/**
 * @author: 特种兵—AK47
 * @创建时间:2012-7-3 上午10:42:34
 *
 * @类说明 :
 */
public class Client {

 public static void main(String[] args) {
  Horse h = new BlackHorse();
  h.eat();
 }

}
 

运行一下:

[html] 
黑马吃草 
黑马吃草
  变量h的

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,