Core Javaノート4.インタフェース

5825 ワード

この章のポイント:
  • interface
  • clone
  • interface & callback
  • proxy

  • interface
      ——           ,         。

    インタフェースの特徴
  • はインタフェースの変数を宣言することができるが、インスタンス化することはできない.
  • interfaceはinstanceof文法をサポートする.
  • interfaceもextendsをサポートする.
  • interfaceは、インスタンスドメインまたは静的メソッドを含むことはできないが、定数(インタフェースのデフォルトはpublic static final)を含むことができる.
  • 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タイプなどの可変タイプについては問題ないが、可変クラスについては問題が発生する.
    クローンメソッドの再定義
  • cloneメソッドを定義する必要があるかどうか.
  • デフォルトのcloneメソッドが要求を満たすかどうか.
  • のデフォルトのcloneメソッドは、可変サブオブジェクトのcloneを呼び出すことによって修正することができるかどうか.
  • はCloneableインターフェースを実現する(Cloneableはtagging interfaceであり、何の方法もない).
  • 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;
    }