Core Java笔记 4.接口

本章重点:

  • interface
  • clone
  • interface & callback
  • proxy

interface

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

接口的特征

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

clone

copy & clone

Employee original = new Employee("John Public", 50000);
Employee copy = original;
copy.raiseSalary(34);   // oops -- also changed original

Employee copy = original.clone();
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 方法.
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 fields
        cloned.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;
}

interface & callback

示例:

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 {

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        Date now = new Date();
        System.out.println("At the tone, time is " + now);
        Toolkit.getDefaultToolkit().beep();
    }
}

proxy

示例:

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 ... 1000
        for (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 value
            elements[i] = proxy;
        }

        Integer key = new Random().nextInt(elements.length) + 1;

        // search for the key
        int result = Arrays.binarySearch(elements, key);

        // print match if found
        if (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;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        // print implicit argument
        System.out.print(target);
        // print mehtod name
        System.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 method
        return method.invoke(target, args);
    }

    private Object target;
}

你可能感兴趣的:(java)