接口和内部类

接口中的所有方法自动地属于public。因此,在接口中声明方法时,不必提供关键字public。接口绝不能含有实例域,也不能在接口中实现方法。接口中的域将被自动设为public static final就是常量,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问属性。

接口不能实例化,但是可以声明变量,变量必须引用实现了接口的类对象。比如A是一个接口,Aa = new B();B必须实现了A。好像多态啊。

接口可以继承,类可以实现实现多个接口,只能继承一个。instanceof可以用来判断是不是实现了接口。

拷贝是两个实例引用同一个对象,改变其中一个会另一个有影响。clone克隆是引用不同的对象,但是这两个实例的相等的,只要实例中没有可改变的子对象,那改变其中一个不会对另一个产生影响子对象也用clone()方法就可以解决有可变子对象的情况

对于类可以判断1.默认的clone方法是否满足要求。2.默认的clone方法是否能够通过调用可变子对象的clone得到修补。3.是否不应该使用clone.实际上,选项3是默认的。如果要选择1或2,类必须:实现Cloneable接口,使用public访问修饰符重新定义clone方法(Object类中的clone方法声明为protected)。

如果默认的clone()就可以实现的话,实现clone()方法就直接调用super.clone()就行了。

有子对象:

public xxx clone() throws xxx{抛出CloneNot-SupportException

        xxx a = (xxx)super.clone();返回object

       a.b = (b的类型)b.clone();b是可变子对象,string不可变。

       return a;

}

需要谨慎使用克隆。数组也有clone(),public类型的


内部类

普通内部类声明:B是A的内部类,Aa =new A();A.B b = a.new B();

1.内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据

2.内部类可以对同一个包中的其他类隐藏起来。

3.当想要定义一个回调函数且不想编写大量代码时,使用匿名( anonymous)内部类比较便捷。

局部类不能用public或private访问说明符进行声明。它的作用域被限定在声明这个局部类的块中。局部类有一个优势,即对外部世界可以完全地隐藏起来。局部类访问局部变量,那些局部变量必须被声明为final。

由于构造器的名字必须与类名相同,而匿名类没有类名,所以,匿名类不能有构造器。取而代之的是,将构造器参数传递给超类(superclass)构造器。尤其是在内部类实现接口的时候,不能有任何构造参数,因为没有没有构造函数。

在内部类不需要访问外围类对象的时候,应该使用静态内部类。

声明在接口中的内部类自动成为static和public。


实现comparable接口,里面有compareTo();可以重写比较。


代理

利用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。

代理类要实现指定接口所需要的全部方法。Object类中的全部方法,例如, toString、 equals等。


代理类是在程序运行过程中创建的。所有的代理类都扩展于Proxy类。一个代理类只有一个实例域—调用处理器,它定义在Proxy的超类中。为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。
对于特定的类加载器和预设的一组接口来说,只能有一个代理类。也就是说,如果使用同一个类加载器和接口数组调用两次newProxyInstance方法的话,那么只能够得到同一个类的两个对象。


代理类一定是public和final。如果代理类实现的所有接口都是public,代理类就不属于某个特定的包;否则,所有非公有的接口都必须属于同一个包,同时,代理类也属于这个包。可以通过调用Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类。


下面的例子使用代理对象对二分查找进行跟踪


package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;
public class Test{
	public static void main(String[] args) {
		Object[] element = new Object[1000];
		for(int i=0;i<element.length;i++){
			Integer value=i+1;
			InvocationHandler handler = new T(value);
			Object proxy = Proxy.newProxyInstance(null, new Class[]{Comparable.class},handler);
			element[i]=proxy;
		}
		Integer key = new Random().nextInt(element.length)+1;
		int result = Arrays.binarySearch(element, key);
		if(result>=0)
			System.out.println(element[result]);
	}
}

  class T implements InvocationHandler {
	private Object target;
	T(Object a){
		target = a;
	}
	
	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);
	}
	
}

结果为

500,compareTo(187)
250,compareTo(187)
125,compareTo(187)
187,compareTo(187)
187,toString()
187
代理类实现了comparable接口,所以invoke就是compareTo方法。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值