package com.ebao.java.innerclass;

public interface Service {
 void method1();
 void method2();
}

 

public interface ServiceFactory {
 Service getService();
}

 

public class Implementation1 implements Service {
 private Implementation1(){}

 @Override
 public void method1() {
  System.out.println("Implementation1 method1");
 }

 @Override
 public void method2() {
  System.out.println("Implementation1 method2");
 }
 public static ServiceFactory factory = new ServiceFactory(){
  public Service getService(){
   return new Implementation1();
  }
 };
}

 

public class Implementation2 implements Service {
 private Implementation2(){}

 @Override
 public void method1() {
  System.out.println("Implementation2 method1");
 }

 @Override
 public void method2() {
  System.out.println("Implementation2 method2");
 }
 public static ServiceFactory factory = new ServiceFactory(){
  public Service getService(){
   return new Implementation2();
  }
 };
}

 

public class Factorys {
 public static void serviceConsumer(ServiceFactory fact){
  Service s = fact.getService();
  s.method1();
  s.method2();
 }
 public static void main(String[] args){
  serviceConsumer(Implementation1.factory);
  serviceConsumer(Implementation2.factory);
 }
}

运行结果:

Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2

 

Implementation1和Implementation2的构造器都是Private的,且没有任何必要去创建作为工厂的具名类。另外,经常只需要单一的工厂对象,因此本例中它被创建为Service实现中的一个Static域。这样所产生的语法也更具有实际意义。

 

如下是个练习,分别用内部类和匿名内部类实现。

内部类:

package com.ebao.java.innerclass;

public class Chapter10Practice7 {
 private String field;
 private void method(){
  System.out.println("Chapter10Practice7.method() ");
  System.out.println("Chapter10Practice7.field: "+field);
 }
 
 class Inner{
  void innerMethod(){
   field = "updated by innerMethod()";
   method();
  }
 }
 Inner getInner(){
  return new Inner();
 }
 public static void main(String[] arg){
  Chapter10Practice7 cp = new Chapter10Practice7();
  Inner ir = cp.getInner();
  ir.innerMethod();
 }
}

运行结果:

Chapter10Practice7.method()
Chapter10Practice7.field: updated by innerMethod()

 

匿名内部类:

package com.ebao.java.innerclass;

abstract class Chapter10Practice12Inner {
 abstract void innerMethod();
}

 

public class Chapter10Practice12 {
 private String field;
 private void method(){
  System.out.println("Chapter10Practice12Inner.method() ");
  System.out.println("Chapter10Practice12Inner.field: "+field);
 }
 
 Chapter10Practice12Inner getInner(){
  return new Chapter10Practice12Inner(){
   void innerMethod(){
    field = "updated by innerMethod()";
    method();
   }
  };
 }
 public static void main(String[] arg){
  Chapter10Practice12 cp = new Chapter10Practice12();
  Chapter10Practice12Inner ir = cp.getInner();
  ir.innerMethod();
 }
}

运行结果:

Chapter10Practice12Inner.method()
Chapter10Practice12Inner.field: updated by innerMethod()

 

为什么需要内部类:

一般来说,内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外围类的对象。所以可以认为内部类提供了某种进入其外围类的窗口。

内部类必须要回答的一个问题是:如果只是需要一个对接口的引用,为什么不通过外围类实现那个接口呢?答案是:“如果这能满足需求,那么就应该这样做。”那么内部类实现一个接口与包围类实现一个接口有什么区别呢?答案是:后者不是总能享用到接口带来的方便,有时需要用到接口的实现,所以使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

使用内部类,还有如下特性:

  1. 内部类可以有多个实例,每个实例都有自己的状态信息。并且与外围类折信息相互独立。
  2. 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
  3. 创建内部类对象的时刻并不依赖于外围类对象的创建。
  4. 内部类并没有令人迷惑的“is-a"关系;它就是一个独立的实体。

举个例子,如果下例中的Sequence.java不使用内部类,就必须声明“Sequence是一个Selector”,对于某个特定的Sequence只能有一个Selector。然而使用内部类很容易就能拥有另一个方法reversseSelector(),用它来生成一个反方向遍历的Selector。只有内部类才有这种灵活性。

package com.ebao.java.innerclass;

public class Sequence {
 private Object[] items;
 private int next = 0;
 private String field;
 public Sequence(int size, String field){
  items =new Object[size];
  this.field = field;
 }
 public void add(Object x){
  if(next < items.length)
   items[next++] = x;
 }
 
 private class SequenceSelector implements Selector{
  private int i = 0;

  public boolean end() {
   return i == items.length;
  }

  public Object current() {
   return items[i];
  }

  public void next() {
   if(i < items.length) i++;
  }
 }
 
 Selector reverseSelector(){
  return new Selector(){
   private int i = items.length-1;
   public boolean end() {
    return i == -1;
   }
   public Object current() {
    return items[i];
   }
   public void next() {
    if(i >= 0) i--;
   }
  };
 }
 
 public Selector selector(){
  return new SequenceSelector();
 }
 public static void main(String[] args){
  Sequence sequence = new Sequence(10,"test1");
  for(int i=0;i<10;i++){
   sequence.add(Integer.toString(i));
  }
  Selector selector = sequence.selector();
  while(!selector.end()){
   System.out.print(selector.current() + " ");
   selector.next();
  }
  System.out.println();
  System.out.println("reverseSelector================================================================ ");
  Selector reverseSelector = sequence.reverseSelector();
  while(!reverseSelector.end()){
   System.out.print(reverseSelector.current() + " ");
   reverseSelector.next();
  }
 }
}

运行结果:

0 1 2 3 4 5 6 7 8 9
reverseSelector================================================================
9 8 7 6 5 4 3 2 1 0

posted on 2015-09-08 17:21  幸运叶  阅读(151)  评论(0编辑  收藏  举报