import java.util.Arrays; class Processor{ public String getName(){ return getClass().getSimpleName(); } Object process(Object input){ return input; } } class Upcase extends Processor{ String process(Object input){ return ((String)input).toUpperCase(); } } class Downcase extends Processor{ String process(Object input){ return ((String)input).toLowerCase(); } } class Spliter extends Processor{ String process(Object input){ return Arrays.toString(((String)input).split(" ")); } } public class Apply { public static void process(Processor p, String s){ System.out.println("Using processor " + p.getName()); System.out.println(p.process(s)); } public static String s = "Disagreement with beliefs is by definition incorrect"; public static void main(String[] args){ process(new Upcase(), s); process(new Downcase(), s); process(new Spliter(), s); } }Apply.process()方法可以接受任何类型的Processor,并将其应用到一个Object对象上。本例这样,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。
在实现的时候一般不创建基类,只是创建一个接口,这样别人在使用时只需implements接口,而非继承基类。
public interface Destination { String readLabel();
public interface Contents { int value(); }
public class Pracel { public Destination destination(String s){ class PDestination implements Destination{ private String label; private PDestination(String whereTo){ label = whereTo; } @Override public String readLabel() { // TODO Auto-generated method stub return label; } } return new PDestination(s); } public static void main(String[] args) { // TODO Auto-generated method stub Pracel p = new Pracel(); Destination d = p.destination("Tasmania"); } }
public class Pracel { public Contents contents(){ return new Contents(){ private int i = 11; public int value(){return i;} }; } public static void main(String[] args) { // TODO Auto-generated method stub Pracel p = new Pracel(); Contents c = p.contents(); } }
public class Pracel { public Destination destination(<span style="color:#ff0000;">final </span>String s) { return new Destination() { private String label = s; @Override public String readLabel() { // TODO Auto-generated method stub return label; } }; } public static void main(String[] args) { // TODO Auto-generated method stub Pracel p = new Pracel(); Destination d = p.destination("Tasmania"); } }如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,则这个参数引用必须是final的。因为方法结束,变量消失,而内部类不会消失,只有final,内部类会拷贝一份进行存储及访问。
当方法destination被调用,从而在它的调用栈中生成了变量s,此时产生了一个局部内部类对象Destination,它访问了该局部变量s .当方法destination()运行结束后,局部变量i就已死亡了,不存在了.但:局部内部类对象Destination还可能 一直存在(只能没有人再引用该对象时,它才会死亡),它不会随着方法destination()运行结束死亡.这时:出现了一个"荒唐"结果:局部内部类对象Destination要访问一个已不存在的局部变量i!
如何才能实现?当变量是final时,通过将final局部变量"复制"一份,复制品直接作为局部内部中的数据成员.这样:当局部内部类访问局部变量 时,其实真正访问的是这个局部变量的"复制品"(即:这个复制品就代表了那个局部变量).因此:当运行栈中的真正的局部变量死亡时,局部内部类对象仍可以 访问局部变量(其实访问的是"复制品"),给人的感觉:好像是局部变量的"生命期"延长了.
举例:要实现在一个方法中匿名调用ABSClass的例子
public static void test(final String s){ //或final String s = "axman"; ABSClass c = new ABSClass(){ public void m(){ int x = s.hashCode(); System.out.println(x); } }; //其它代码. }编译的时候,其实是这样的:
public static void test(final String s){ //或final String s = "axman"; class OuterClass$1 extends ABSClass{ private final String s; public OuterClass$1(String s){ this.s = s; } public void m(){ int x = s.hashCode(); System.out.println(x); } }; ABSClass c = new OuterClass$1(s); //其它代码. }即外部类的变量被作为构造方法的参数传给了内部类的私有成员.
abstract class Base{ public Base(int i){ System.out.println("Base constructor,i = " + i); } public abstract void f(); } public class AnonymousConstructor { public static Base getBase(int i){ return new Base(i){ @Override public void f() { // TODO Auto-generated method stub System.out.println("In anonymous f()"); } }; } public static void main(String[] args) { // TODO Auto-generated method stub Base base = getBase(47); base.f(); } }
接口是一种协定,抽象类则相当于类模板。
使用抽象类,而不要使用接口来分离协定与实现。
如果需要提供多态层次结构的值类型,使用接口。
如果一个类型必须实现多个协定,或者协定适用于多种类型,使用接口。
虽然抽象类和接口都支持将协定与实现分离开来,但接口不能指定以后版本中的新成员,而抽象类可以根据需要添加成员以支持更多功能。
优先考虑定义类,而不是接口。
由于每个类都会生成一个.class的文件,其中共包含了如何创建该类型的对象的全部信息(此信息产生一个"meta-class",叫做class对象),内部类也必须生成一个.class文件以包含它们的class对象信息。这些类名有严格的命名规则:外围类名字+"$"+内部类名字,如:
interface Counter{ int next(); } public class LocalInnerClass{ private int count = 0; Counter getCounter(final String name){ class LocalCounter implements Counter{ public LocalCounter(){ System.out.println("LocalCounter()"); } public int next(){ System.out.print(name); return count++; } } return new LocalCounter(); } Counter getCounter2(final String name){ return new Counter(){ { System.out.println("Counter()"); } @Override public int next() { // TODO Auto-generated method stub System.out.print(name); return count++; } }; } public static void main(String[] args){ LocalInnerClass lic = new LocalInnerClass(); Counter c1 = lic.getCounter("Local inner"), c2 = lic.getCounter2("Anonymous inner"); for(int i = 0; i < 5; ++i){ System.out.println(c1.next()); } for(int i = 0; i < 5; ++i){ System.out.println(c2.next()); } } }
输出结果为:
Counter() Local inner0 Local inner1 Local inner2 Local inner3 Local inner4 Anonymous inner5 Anonymous inner6 Anonymous inner7 Anonymous inner8 Anonymous inner9生成的.class文件包括:
Counter.class, LocalInnerClass$1.class, LocalInnerClass$1LocalCounter.class,LocalInnerClass.class