[关闭]
@gnudennis 2015-04-26T22:50:21.000000Z 字数 3888 阅读 1959

Core Java笔记 4.接口

CoreJava


本章重点:

  • interface
  • clone
  • interface & callback
  • proxy

interface

接口——如果类遵从某个特定接口,那么就履行这项服务。

接口的特征

  1. 可以声明接口的变量,但是不可以实例化.
  2. interface 支持 instanceof 语法.
  3. interface 同样支持 extends.
  4. interface 不可以包含实例域或者静态方法,但是可以包含常量(接口中默认是public static final).
  5. java 支持“单继承、多接口”.

clone

copy & clone

  1. Employee original = new Employee("John Public", 50000);
  2. Employee copy = original;
  3. copy.raiseSalary(34); // oops -- also changed original
  4. Employee copy = original.clone();
  5. copy.raiseSalary(10); // OK -- original unchanged

cloneObject的 protected 方法,由于 Object 类对具体类的一无所知,所以默认只是对各个域浅拷贝, 这对于基本类型和不可变类型(如String类型)没有问题,但是对于可变类(mutable class)却会出问题.

重新定义 clone 方法

  1. 是否需要定义 clone 方法.
  2. 默认的 clone 方法是否满足要求.
  3. 默认的 clone 方法是否能够通过调用可变子对象的 clone 得到修补.
  4. 实现 Cloneable 接口(Cloneable 是tagging interface,没有任何方法).
  5. 使用 public 修饰 clone 方法.
  1. package corejava.interfaces;
  2. import java.util.Date;
  3. import java.util.GregorianCalendar;
  4. /**
  5. * Created by guolong.fan on 15/4/26.
  6. */
  7. public class CloneTest {
  8. public static void main(String[] args) {
  9. try {
  10. Employee origianl = new Employee("John Q. Public", 50000);
  11. origianl.setHireDay(2015, 4, 26);
  12. Employee copy = origianl.clone();
  13. copy.raiseSalary(10);
  14. copy.setHireDay(2015, 5, 1);
  15. System.out.println("orginal=" + origianl);
  16. System.out.println("copy=" + copy);
  17. } catch (CloneNotSupportedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. class Employee implements Cloneable {
  23. public Employee(String n, double s) {
  24. name = n;
  25. salary = s;
  26. hireDay = new Date();
  27. }
  28. public Employee clone() throws CloneNotSupportedException {
  29. // call Object.clone()
  30. Employee cloned = (Employee) super.clone();
  31. // clone mutable fields
  32. cloned.hireDay = (Date)hireDay.clone();
  33. return cloned;
  34. }
  35. public void setHireDay(int year, int month, int day) {
  36. Date newHireDay = new GregorianCalendar(year, month-1, day).getTime();
  37. hireDay.setTime(newHireDay.getTime());
  38. }
  39. public void raiseSalary(double byPercent) {
  40. double raise = salary * byPercent / 100;
  41. salary += raise;
  42. }
  43. public String toString() {
  44. return getClass().getSimpleName() +
  45. "[name=" + name +
  46. ",salary=" + salary +
  47. ",hireDay=" + hireDay + "]";
  48. }
  49. private String name;
  50. private double salary;
  51. private Date hireDay;
  52. }

interface & callback

示例:

  1. package corejava.interfaces;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.util.Date;
  7. /**
  8. * Created by guolong.fan on 15/4/26.
  9. */
  10. public class TimerTest {
  11. public static void main(String[] args) {
  12. ActionListener listener = new TimePrinter();
  13. Timer t = new Timer(5000, listener);
  14. t.start();
  15. JOptionPane.showMessageDialog(null, "Quit program?");
  16. System.exit(0);
  17. }
  18. }
  19. class TimePrinter implements ActionListener {
  20. @Override
  21. public void actionPerformed(ActionEvent actionEvent) {
  22. Date now = new Date();
  23. System.out.println("At the tone, time is " + now);
  24. Toolkit.getDefaultToolkit().beep();
  25. }
  26. }

proxy

示例:

  1. package corejava.interfaces;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import java.util.Arrays;
  6. import java.util.Random;
  7. /**
  8. * Created by guolong.fan on 15/4/26.
  9. *
  10. * This program demonstrates the use of proxies.
  11. */
  12. public class ProxyTest {
  13. public static void main(String[] args) {
  14. Object[] elements = new Object[1000];
  15. // 给 1...100 构造代理.
  16. // fill elements with proxies for the integers 1 ... 1000
  17. for (int i = 0; i < elements.length; ++i) {
  18. Integer value = i + 1;
  19. InvocationHandler handler = new TraceHandler(value); // method.invoke(target, args);
  20. Object proxy = Proxy.newProxyInstance(null, new Class[] {Comparable.class}, handler);
  21. // now proxy is proxy of value
  22. elements[i] = proxy;
  23. }
  24. Integer key = new Random().nextInt(elements.length) + 1;
  25. // search for the key
  26. int result = Arrays.binarySearch(elements, key);
  27. // print match if found
  28. if (result >= 0) System.out.println(elements[result]);
  29. }
  30. }
  31. /**
  32. * An invocation handler that prints out the method name and parameters, then
  33. * invokes the original method
  34. */
  35. class TraceHandler implements InvocationHandler {
  36. public TraceHandler(Object t) {
  37. target = t;
  38. }
  39. @Override
  40. public Object invoke(Object o, Method method, Object[] args) throws Throwable {
  41. // print implicit argument
  42. System.out.print(target);
  43. // print mehtod name
  44. System.out.print("." + method.getName() + "(");
  45. if (args != null) {
  46. for (int i = 0; i < args.length; ++i) {
  47. if (i > 0) System.out.print(", ");
  48. System.out.print(args[i]);
  49. }
  50. }
  51. System.out.println(")");
  52. // invoke actual method
  53. return method.invoke(target, args);
  54. }
  55. private Object target;
  56. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注