Java核心技术-接口与内部类
一.接口
1.引用接口的原因:一个类只能扩展于一个类,当一个类要实现多种功能时,Java中不能多继承,可以通过实现多个接口来实现,这样也避免了多重继承的复杂性和低效性。
(每个类只能拥有一个超类,但可以实现多个接口。灵活性)
2.如何让类实现一个接口:
(1)使用关键字 "implements" 将类声明为实现给定的接口;
(2)对接口中所有的方法进行定义。
class Employee implements Comparable
3.如何检查一个对象是否实现了某个接口:
用instance
if (anObject instanceof Comparable){ ... }
3.接口的特性:
(1)接口不是类,而是对类的一组需求描述,确保类实现某个或一组特定方法;
(2)接口不能含有实例域或静态方法,可包含常量;
(3)在接口中不能实现方法,接口中所有方法都自动设置为public,域自动设置为public static final;
(4)不能构造接口的对象,可以声明接口的对象;
(5)接口可以被扩展。
二.对象克隆
1.对象的克隆(clone):创建一个新对象,其状态与原始对象的状态相同。修改克隆的新对象不会影响对象的状态,可以各自改变各自的状态。
clone方法是Object类的一个protected方法。此时不能使用super.clone()
2.浅拷贝:默认的克隆操作,没有克隆包含在对象中的内部对象。原始对象与克隆对象共享的子对象不可变时。
深拷贝:原始对象与克隆对象共享的子对象可变时。必须克隆所有可变的实例域。此时必须重新定义clone方法以实现深拷贝。
3.如何重新定义clone方法:
首先要判断:(1)默认的clone方法是否满足要求;(2)默认的clone方法是否能够通过调用可变子对象的clone得到修补;(3)是否不应该使用clone。
操作:(1)实现Cloneable接口;(2)使用public重新定义clone方法,这样才能让所有方法克隆对象。
//建立深拷贝clone方法 class Employee implements Cloneable{ ... public Employee clone() throws CloneNotSupportedException{ Employee cloned = (Employee) super.clone(); cloned.hireDay = (Date) hireDay.clone(); return cloned; } }
4.注意:Cloneable接口并没有指定clone方法,clone方法从Object类继承。Cloneable接口只是作为一个标记,表明知道要进行克隆处理。标记接口没有方法,使用标记接口的目的是可以用instanceof进行类型检查。
三.接口与回调
1.回调是一种程序设计模式,它可以指出某个特定事件发生时应该采取的动作。
四.内部类
1.内部类是定义在另一个类中的类,其中的方法可以访问包含它们的外部类的域。
2.内部类的优势:
(1)可以访问该类定义所在作用域的数据,包括私有的数据;
(2)可以对同一个包中的其他类隐藏起来;
(3)当想定义一个回调函数且不想写大量代码时,使用匿名内部类就很方便。
3.注意:
(1)内部类是一种编译器现象,与虚拟机无关。
(2)只有内部类可以是私有类,常规类只能是具有包可见性或者公有可见性。
4.使用内部类访问对象状态:内部类既可以访问自身数据域,也可以访问创建它的外围类对象的数据域,内部类可以有一个外围类的引用outer。
5.局部内部类优点:
(1)对外部世界可以完全隐藏,它的作用域被限定在声明这个局部类的块中。不能用public或private声明。
(2)不仅能够访问包含它们的外部类,还可以访问局部变量。要注意局部类的方法只可以引用定义为fianal的局部变量。
6.匿名内部类:内部类中若只创建这个类的一个对象,就不用命名了。而这种类被称为匿名类。
注意:匿名类不能有构造器,而直接将构造器参数传递给超类构造器。
代码中,若构造参数的闭圆括号后面跟了一个花括号,那么花括号中正在定义的就是匿名内部类。
Person count = new Person("Dracula") { ... }
7.静态内部类:当只需要把一个类隐藏在另一个类的内部,并不需要内部类引用外围类对象时,可以将内部类声明为static来取消产生的引用。
五.代理
1.代理是一项工具构造者感兴趣的高级技术。
代理类在运行时创建全新的类,这样的代理类能够实现指定的接口。一旦被创建,就变成了常规类。当在编译时无法确定要实现哪个接口时才有必要运用这种功能。
使用代理的一些情形:(1)路由对远程服务器的方法调用;(2)在程序运行期间,将用户接口事件与动作关联起来;(3)为调试,跟踪方法调用。
2.不能在运行时定义这些方法的新代码,而是要提供一个调用处理器。调用处理器是实现接口的类对象。
3.调用代理对象的方法,调用处理器的invoke方法都会被调用,并向其传递Mothod对象和原始的调用参数。
4.如何创建一个代理对象:需使用Proxy类的newProxyInstance方法,该方法有三个参数。类加载器、Class对象数组、调用处理器。
5.代理类的特性:
(1)所有代理类都扩展于Proxy类。
(2)一个代理类只有一个实例域——调用处理器,定义在Proxy的超类中。
(3)为了履行代理对象的职责,任何所需的附加数据都要存储在调用处理器中。

浙公网安备 33010602011771号