对类的一组需求描述,遵从接口描述的统一格式
接口中的所有方法自动的属于public
有些接口可能有多个方法
接口不能含有实例域,不能在接口中实现方法
类实现接口:将类声明为实现给定的某个接口,对接口中的所有方法进行定义
将类声明为实现某个接口,使用关键字implements
java是一种强类型语言,调用方法是,编译器会检查这个方法是否存在
可以声明接口的变量,不能构造接口的对象,可以包含常量
接口变量必须引用实现了接口的对象
接口可以被扩展
每个类只能够有一个超类,可以实现多个接口
class Employee implements Cloneable,Comparable抽象类只能扩展一个类,每个类可以实现多个接口
java不允许一个类有多个超类(多继承)
当拷贝一个变量时,原始变量与拷贝变量引用同一个对象
浅拷贝:对域拷贝,没有克隆包含在对象中的内部对象,使两个域引用同一个子对象,子对象是不可变的
Employee copy = original;//原始对象与拷贝对象引用同一个对象 Employee copy = original.clone();//浅拷贝clonerable接口从Object类继承而来,作为一个标记,表明类设计者知道要进行克隆处理
class Employee implements Cloneable { //在clone中没有实现接口,抛出异常CloneNot-SupportedException public Employee clone() throws CloneNotSupportedException { //克隆对象 Employee cloned = (Employee) super.clone(); //克隆实例域 cloned.hireDay = (Date) hireDay.clone(); return cloned; } } import java.util.*; public class CloneTest { public static void main(String[] args) { try { Employee original = new Employee("jaon",50000); original.setHireDay(2000,1,1); Employee copy = original.clone(); copy.raiseSalary(10); copy.setHireDay(2002,12,31); System.out.println("original=" + original); 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 { //克隆对象 Employee cloned = (Employee) super.clone(); //克隆实例域 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 "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; } private String name; private double salary; private Date hireDay; }回调:某个特定时间发生时应该采取的动作
java.swing包中有一个Timer类,在到达给定的时间间隔时发出通告
内部类方法可以访问该类定义所在作用域中的数据,包括私有的数据
内部类可以对同一个包中的其他类隐藏起来
定义一个回调函数使用匿名内部类比较便捷
嵌套类是一种类之间的关系,命名控制和访问控制
java内部类的对象有一个隐式引用,引用了实例化该内部对象的外围类对象
一个方法可以引用调用这个方法的对象数据域,内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域
内部类的对象总有一个隐式调用,指向创建它的外部类对象
可以显式的命名将外围类引用设置为其他的对象
不能用public和private访问说明符
可以对外部世界完全隐藏起来
把一个类隐藏在另外一个类的内部
pair容易产生名字冲突,将pair定义为内部公有类
在内部类不需要访问外围类对象时,使用静态内部类
public class StaticInnerClassTest { public static void main(String[] args) { double[] d = new double[20]; for (int i = 0; i < d.length; i++) d[i] = 100 * Math.random(); //内部公有类,防止产生命名冲突 ArrayAlg.Pair p = ArrayAlg.minmax(d); System.out.println("min = " + p.getFirst()); System.out.println("max = " + p.getSecond()); } } class ArrayAlg { //静态内部类 public static class Pair { public Pair(double f,double s) { first = f; second = s; } public double getFirst() { return first; } public double getSecond() { return second; } private double first; private double second; } public static Pair minmax(double[] values) { double min = Double.MAX_VALUE; double max = Double.MIN_VALUE; for(double v:values) { if(min > v) min = v; if(max < v) max = v; } //内部类对象在静态方法中构造 return new Pair(min,max); } }在运行时创建一个实现了一组接口的新类
在编译时无法确定实现哪个接口时使用
使用代理:路由对远程服务器的方法调用,在程序运行期间将用户接口事件与动作关联起来,为调试跟踪方法调用
构造用于跟踪方法调用的对象
Object value = ; InvozationHandler = new TraceHandler(value); //创建代理 Class[] interfaces = new Class[] {Comparable.class}; Object proxy = Proxy.newProxyInstance(nulll,interfaces,handler); import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.*; public class ProxyTest { //使用代理对象对二分查找进行跟踪 public static void main(String[] args) { Object[] elements = new Object[1000]; //给proxies赋值 for(int i = 0; i < elements.length; i++) { Integer value = i + 1; //构造拥有跟踪方法调用的代理对象 InvocationHandler handler = new TraceHandler(value); Object proxy = Proxy.newProxyInstance(null,new Class[] {Comparable.class},handler); elements[i] = proxy; } //构造一个任意整数 Integer key = new Random().nextInt(elements.length) + 1; //搜索key,使用二分查找 int result = Arrays.binarySearch(elements, key); //打印符合的结果 if(result >= 0) System.out.println(elements[result]); } } //调用处理器接口的类对象 class TraceHandler implements InvocationHandler { public TraceHandler(Object t) { target = t; } //打印出被调用方法的名字和参数 public Object invoke(Object proxy,Method m,Object[] args) throws Throwable { System.out.print(target); System.out.print("." + m.getName() + "("); if (args != null) { //打印方法的名字和参数 for(int i = 0;i < args.length; i++) { System.out.print(args[i]); if(i < args.length - 1) System.out.print(", "); } } System.out.println(")"); //用包装好的对象作为隐式参数与调用这个方法 return m.invoke(target, args); } private Object target; }