@gnudennis
2015-04-26T14:50:21.000000Z
字数 3888
阅读 2063
CoreJava
- interface
- clone
- interface & callback
- proxy
接口——如果类遵从某个特定接口,那么就履行这项服务。
- 可以声明接口的变量,但是不可以实例化.
- interface 支持 instanceof 语法.
- interface 同样支持 extends.
- interface 不可以包含实例域或者静态方法,但是可以包含常量(接口中默认是public static final).
- java 支持“单继承、多接口”.
Employee original = new Employee("John Public", 50000);Employee copy = original;copy.raiseSalary(34); // oops -- also changed originalEmployee copy = original.clone();copy.raiseSalary(10); // OK -- original unchanged
clone是Object的 protected 方法,由于 Object 类对具体类的一无所知,所以默认只是对各个域浅拷贝, 这对于基本类型和不可变类型(如String类型)没有问题,但是对于可变类(mutable class)却会出问题.
package corejava.interfaces;import java.util.Date;import java.util.GregorianCalendar;/*** Created by guolong.fan on 15/4/26.*/public class CloneTest {public static void main(String[] args) {try {Employee origianl = new Employee("John Q. Public", 50000);origianl.setHireDay(2015, 4, 26);Employee copy = origianl.clone();copy.raiseSalary(10);copy.setHireDay(2015, 5, 1);System.out.println("orginal=" + origianl);System.out.println("copy=" + copy);} catch (CloneNotSupportedException e) {e.printStackTrace();}}}class Employee implements Cloneable {public Employee(String n, double s) {name = n;salary = s;hireDay = new Date();}public Employee clone() throws CloneNotSupportedException {// call Object.clone()Employee cloned = (Employee) super.clone();// clone mutable fieldscloned.hireDay = (Date)hireDay.clone();return cloned;}public void setHireDay(int year, int month, int day) {Date newHireDay = new GregorianCalendar(year, month-1, day).getTime();hireDay.setTime(newHireDay.getTime());}public void raiseSalary(double byPercent) {double raise = salary * byPercent / 100;salary += raise;}public String toString() {return getClass().getSimpleName() +"[name=" + name +",salary=" + salary +",hireDay=" + hireDay + "]";}private String name;private double salary;private Date hireDay;}
示例:
package corejava.interfaces;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Date;/*** Created by guolong.fan on 15/4/26.*/public class TimerTest {public static void main(String[] args) {ActionListener listener = new TimePrinter();Timer t = new Timer(5000, listener);t.start();JOptionPane.showMessageDialog(null, "Quit program?");System.exit(0);}}class TimePrinter implements ActionListener {@Overridepublic void actionPerformed(ActionEvent actionEvent) {Date now = new Date();System.out.println("At the tone, time is " + now);Toolkit.getDefaultToolkit().beep();}}
示例:
package corejava.interfaces;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;import java.util.Random;/*** Created by guolong.fan on 15/4/26.** This program demonstrates the use of proxies.*/public class ProxyTest {public static void main(String[] args) {Object[] elements = new Object[1000];// 给 1...100 构造代理.// fill elements with proxies for the integers 1 ... 1000for (int i = 0; i < elements.length; ++i) {Integer value = i + 1;InvocationHandler handler = new TraceHandler(value); // method.invoke(target, args);Object proxy = Proxy.newProxyInstance(null, new Class[] {Comparable.class}, handler);// now proxy is proxy of valueelements[i] = proxy;}Integer key = new Random().nextInt(elements.length) + 1;// search for the keyint result = Arrays.binarySearch(elements, key);// print match if foundif (result >= 0) System.out.println(elements[result]);}}/*** An invocation handler that prints out the method name and parameters, then* invokes the original method*/class TraceHandler implements InvocationHandler {public TraceHandler(Object t) {target = t;}@Overridepublic Object invoke(Object o, Method method, Object[] args) throws Throwable {// print implicit argumentSystem.out.print(target);// print mehtod nameSystem.out.print("." + method.getName() + "(");if (args != null) {for (int i = 0; i < args.length; ++i) {if (i > 0) System.out.print(", ");System.out.print(args[i]);}}System.out.println(")");// invoke actual methodreturn method.invoke(target, args);}private Object target;}