java匿名类工厂方法[java编程思想10.6.1]

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

时间: 2024-12-25 04:55:08

java匿名类工厂方法[java编程思想10.6.1]的相关文章

解决内存泄漏更加清楚的认识到Java匿名类与外部类的关系

1.事件起因 在做项目的时候,通过Android Studio的Memory Monitor窗口观察程序内存使用情况,发现当程序退出的时候,有一部分应该释放掉的内存没有释放掉,知道程序中应该有内存泄漏了.为了发现程序中的内存泄漏,我切换了IDE工具到Eclipse,里面安装了内存泄漏的分析工具MAT,具体怎么用MAT分析内存泄漏可以自己Google,我把我自己找到内存泄漏的地方贴出来 从上图中可以看到,有24M左右的内存被mView(其实它真正是一个Fragment)这个变量持有,导致Java垃

java匿名类和匿名对象及this的其他用法

/* 匿名内部类:就是内部类的简写格式. 必须前提:内部类必须继承或者实现一个类或者接口. 匿名内部类其实就是一个匿名 子类对象. 格式:new 父类对象 or 接口(){ 子类内容:(覆盖父类的, 而且可以增加自己的方法) }//相当于将 继承父类 和 new 的过程 写到了一起有某有!很方便有某有! */ class Outer{ int num; public Outer(){ num = 5; } class Inner{ int num; public Inner(){ num = 1

JAVA学习之工厂方法模式

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口, 这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 原文链接http://tech.it168.com/a2009/0223/266/000000266400.shtml package com.fylx; //定义一个接口,人 interface People { publ

Java设计模式之工厂方法模式(转) 实现是抽象工厂?

Java设计模式之工厂方法模式 责任编辑:覃里作者:Java研究组织   2009-02-25   来源:IT168网站 文本Tag: 设计模式 Java [IT168 技术文章]          一 .工厂方法(Factory Method)模式 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色

自定义类工厂方法

1.自定义工厂方法 什么是工厂方法(快速创建方法) 类工厂方法是一种用于分配.初始化实例并返回一个它自己的实例的类方法.类工厂方法很方便,因为它们允许您只使用一个步骤(而不是两个步骤)就能创建对象. 例如new 自定义类工厂方法的规范 (1)一定是+号开头 (2)返回值一般是instancetype类型 (3)方法名称以类名开头,首字母小写 示例 + (id)person; + (id)person { return [[Person alloc]init]; } + (id)personWit

匿名类使用方法

匿名类的使用将一个类定义在另一个类的里面,对里面那个类就称为匿名类的调用.匿名类的访问特点: 1,匿名类可以直接访问外部类的成员. 2,外部类要访问内部类,必须建立在匿名类的对象.什么时候用? 一般用于类的设计,分析事物时,发现该事物还有事物,并且这个事物还在访问被描述的事物的内容.这时就把还有的事物定义为内部类来描述.内部类也相当与封装.匿名类的修饰符:直接访问外部类中的匿名类的成员: outer.inner in=new outer().new inner();如果匿名类是静态的(内部类成员

24-oc类工厂方法和类对象基本概念

类工厂方法 用于快速创建对象的类方法, 我们称之为类工厂方法 类工厂方法应用场景 类工厂方法中主要用于给对象分配存储空间和初始化这块存储空间 类工厂方法使用规范 规范: 一定是类方法 + 方法名称以类的名称开头, 首字母小写 一定有返回值, 返回值是id/instancetype 在类工厂方法实现中,调用本类的构造方法,创建实例对象,并返回实例对象 自定义类工厂方法是苹果的一个规范, 一般情况下, 我们会给一个类提供自定义构造方法和自定义类工厂方法用于创建一个对象 类工厂方法在继承中的注意点 以

类工厂方法及注意点

+(instancetype)person //p小写 { return [[self alloc] init]; } +(instancetype)personWithAge:(int)age { Person *p= [[self alloc] init]; p.age=age; return p; } 类工厂方法本质:创建一个实体类返回 注意点:创建实体类一定要用self而不是用实体类(此处是Person)

类工厂方法的定义

类工厂方法是一种用于分配.初始化实例并返回一个它自己的实例的类方法.类工厂方法很方便,因为它们允许您只使用一个步骤(而不是两个步骤)就能创建对象. 它们采用以下形式: + (type)className...(在这里 className 不包括任何前缀) 调用类工厂时如:nsstring *string = [nsstring initwithformat:@"jdhj%@",anotherString]