黑马程序员技术交流社区

标题: (已解决)请问这个小程序的输出是什么?为什么? [打印本页]

作者: long    时间: 2013-5-11 22:28
标题: (已解决)请问这个小程序的输出是什么?为什么?
本帖最后由 long 于 2013-5-13 13:12 编辑

interface Incrementable {
     void increment();
}

class Callee1 implements Incrementable {
    private int i = 0;
    public void increment() {
    i++;
    System.out.println(i);
    }
}

class MyIncrement {
   public void increment() { System.out.println("Other operation"); }
   static void f(MyIncrement mi) { mi.increment(); }
}

class Callee2 extends MyIncrement {
    private int i = 0;
    public void increment() {
    super.increment();
    i++;
    System.out.println(i);
   }
   private class Closure implements Incrementable {
      public void increment() {
      Callee2.this.increment();
      }
   }
Incrementable getCallbackReference() {
    return new Closure();
    }
}

class Caller {
    private Incrementable callbackReference;
    Caller(Incrementable cbh) { callbackReference = cbh; }
    void go() { callbackReference.increment(); }
}

public class Callbacks {
    public static void main(String[] args) {
         Callee1 c1 = new Callee1();
         Callee2 c2 = new Callee2();
         MyIncrement.f(c2);
         Caller caller1 = new Caller(c1);
         Caller caller2 = new Caller(c2.getCallbackReference());
         caller1.go();
         caller1.go();
         caller2.go();
         caller2.go();
    }
}


作者: eycrckag    时间: 2013-5-11 22:38
天啊,怎么那么长都没有注释呢!强烈请求加注释!谢谢
作者: long    时间: 2013-5-11 23:07
eycrckag 发表于 2013-5-11 22:38
天啊,怎么那么长都没有注释呢!强烈请求加注释!谢谢

原文没注释啊,不便之处,敬请见谅!
作者: 飞鸟青崖    时间: 2013-5-11 23:09
复制下来,自己运行一次不就可以了。
作者: 潘廖明    时间: 2013-5-12 01:41
想说下哪里找来的题目,这么复杂....扯淡啊,你要是初学者就别看了,我足足分析了一个半小时,为你加了注释。
就差没有画内存分析图。如果没有画内存分析图的话,这一题非常容易出错。
  1. package generic;

  2. /**
  3. *
  4. * @author Administration
  5. *
  6. */

  7. interface Incrementable
  8. {

  9.         /**
  10.          * Incrementable接口中定义一个增加的方法
  11.          */
  12.         void increment();
  13. }

  14. class Callee1 implements Incrementable// Callee1实现了Incrementable接口,复写increment()方法
  15. {
  16.         private int i = 0;

  17.         /*
  18.          * 复写的方法 (non-Javadoc)
  19.          *
  20.          * @see generic.Incrementable#increment()
  21.          */
  22.         public void increment()
  23.         {
  24.                 i++;
  25.                 System.out.println("Callee1---" + i);
  26.         }
  27. }

  28. /**
  29. *
  30. * @author Administration 定义一个普通类
  31. *
  32. */
  33. class MyIncrement
  34. {
  35.         /**
  36.          * 定义了一个方法increment()
  37.          */
  38.         public void increment()
  39.         {
  40.                 System.out.println("MyIncrement------Other operation");
  41.         }

  42.         /**
  43.          * 定义了一个静态方法,实现调用本类的increment()方法
  44.          *
  45.          * @param mi
  46.          */
  47.         static void f(MyIncrement mi)// 传入一个c2变量
  48.         {
  49.                 mi.increment();
  50.         }
  51. }

  52. /**
  53. *
  54. * @author Administrator 一个普通类Callee2继承了 MyIncrement类
  55. *
  56. */
  57. class Callee2 extends MyIncrement
  58. {
  59.         private int i = 0;

  60.         /**
  61.          * 复写了increment()方法
  62.          */
  63.         public void increment()
  64.         {
  65.                 super.increment();// 调用父类的方法
  66.                 i++;
  67.                 System.out.println("MyIncrement----" + i);
  68.         }

  69.         /**
  70.          *
  71.          * @author Administrator 定义了一个内部类实现了Incrementable接口,需要覆盖increment()方法
  72.          */
  73.         private class Closure implements Incrementable
  74.         {
  75.                 public void increment()
  76.                 {
  77.                         Callee2.this.increment();// 内部类调用外部类方法,称为回调
  78.                 }
  79.         }

  80.         Incrementable getCallbackReference()
  81.         {
  82.                 return new Closure();// 新建了Closure的实例对象,然后将其返回
  83.         }
  84. }

  85. class Caller
  86. {
  87.         private Incrementable callbackReference;// 定义了一个接口类型的变量

  88.         /**
  89.          * 通过构造方法初始化Incrementable 类型变量的值
  90.          *
  91.          * @param cbh
  92.          */
  93.         Caller(Incrementable cbh)
  94.         {
  95.                 callbackReference = cbh;
  96.         }

  97.         /**
  98.          * 通过该初始化后的对象调用increment()方法,有可能存在多态,要看具体传入的值
  99.          */
  100.         void go()
  101.         {
  102.                 callbackReference.increment();
  103.         }
  104. }

  105. public class Callbacks
  106. {
  107.         public static void main(String[] args)
  108.         {
  109.                 Callee1 c1 = new Callee1();// 新建了一个Callee1的对象,马上去查看该类是否有父类,
  110.                 // 有则先调用父类的无参构造方法,然后才调用本类的构造方法。有多个间接父类也是一样的。由于都没有实现构造方法所以没有输出结果
  111.                 Callee2 c2 = new Callee2();// 由于MyIncrement与Cllee2都没有实现默认的构造方法,所以什么也没有输出
  112.                 MyIncrement.f(c2);// 先输出:MyIncrement------Other operation
  113.                                                         // 然后输出:MyIncrement----1,
  114.                                                         // 存在多态的现象,调用的Collee2类中的increment()方法。
  115.                 Caller caller1 = new Caller(c1);// 没有构造函数所以没有输出
  116.                 Caller caller2 = new Caller(c2.getCallbackReference());// c2.getCallbackReference()返回new
  117.                                                                                                                                 // Closure();
  118.                                                                                                                                 // 然后:callbackReference
  119.                                                                                                                                 // = new
  120.                                                                                                                                 // Closure();存在多态
  121.                 caller1.go();// 存在多态所以调用的是Collee1中的increment()方法输出:Callee1---1
  122.                 caller1.go();// 同一个对象调用go()所以输出:Callee1---2
  123.                 caller2.go();// 存在多态调用的是Callee2的内部类Closure中的increment()方法:输出MyIncrement------Other
  124.                                                 // operation MyIncrement----2(由于前面的MyIncrement.f(c2)已经输出:MyIncrement----1)
  125.                 caller2.go();// 统一对象调用两次:输出MyIncrement------Other operation
  126.                                                 // MyIncrement----3
  127.         }
  128. }
复制代码

作者: long    时间: 2013-5-13 13:09
潘廖明 发表于 2013-5-12 01:41
想说下哪里找来的题目,这么复杂....扯淡啊,你要是初学者就别看了,我足足分析了一个半小时,为你加了注释 ...

神人啊,再次膜拜!万分感谢!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2