您的位置:首页 > 编程语言 > Java开发

Java核心技术I——基础点拾掇(第六章)

2015-07-05 21:48 295 查看
接口不是类,而是对类的一组需求描述。这些类要遵从接口描述的统一格式进行定义。

接口中的所有方法自动地属于public。因此,在接口中声明方法时,不必提供关键字public。

接口中可以定义常量。但绝不能定义实例域,也不能在接口中实现方法。提供实例域和方法实现的任务应该由实现接口的那个类来完成。

接口的特性:

(1)接口不是类,尤其不能使用new运算符实例化一个接口。

(2)尽管不能构造接口的对象,却能声明接口的变量。(例如:Comparable x;)

(3)接口变量必须引用实现了接口的类对象。

(4)可以使用instance检查一个对象是否实现了某个特定的接口。与可以建立类的继承关系一样,接口也可以被扩展。(一个接口继承自另一个接口)

(5)接口中不能包含实例域或静态方法,但却可以包含常量。

(6)接口中的方法都自动地被设置为public,接口中的域都被设置为public static final。

如果希望自己设计的类拥有克隆和比较的能力,只要实现Cloneable和Comparable接口。

class XXX implements Cloneable, Comparable {}


使用逗号将实现的各个接口分隔开。

为什么Java程序设计语言不辞辛苦地引入接口概念?为什么不将Comparable直接设计成用于继承的抽象类?

使用抽象类表示通过属性存在一个问题:每个类只能扩展于一个类。

C++中允许继承多个类(多继承),而Java不支持多继承,因为多继承会让语言本身边的非常复杂,效率也会降低。

而Java类却可以实现多个接口!

接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性。

对象克隆:

clone方法时Object类的一个protected方法。

在标准类库中,只有不到5%的类实现了clone。因为要实现clone,必须知道当前类所包含的所有域。如果所有数据域都属于数值或基本类型,这样的拷贝域没有任何问题。但是,如果在对象中包含了子对象的引用,拷贝的结果会使得两个域引用同一个子对象,因此原始对象与克隆对象共享这部分信息(浅拷贝)。

接口与回调:

在很多程序设计语言中,可以提供一个函数名,定时器周期性的调用它。但是,在Java标准类库中的类采用的是面向对象方法。它将某个类的对象传递给定时器,然后,定时器调用这个对象的方法。由于对象可以携带一些附加的信息,所以传递一个对象比传递一个函数要灵活得多。

当然,定时器需要知道调用哪一个方法,并要求传递的对象所属的类实现了java.awt.event包的ActionListener接口。,当到达指定时间间隔时,定时器就调用actionPerformed方法。

// 定时器:javax.swing.Timer

内部类:(inner class)是定义在另一个类中的类。 // 有兴趣宜可入了解!

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

内部类的对象有一个隐式引用,它引用了实例化该内部对象的外围类对象。通过这个指针,可以访问外围类对象的全部数据。

内部类既可以访问自身的数据域,也可以访问创建他的外围类对象的数据域

(2)内部类可以对同一个包中的其他类隐藏起来。(只有内部类可以是私有类)外围类中的其他代码也不能访问它

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

(4)只有内部类可以声明为static。静态内部类的对象没有对生成它的外围类对象的引用特权

代理:

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

假设有一个表示接口的Class对象(有可能只包含一个接口),它的确切类型在编译时无法知道。这确实有些难度。要想构造一个实现这些接口的类,就需要使用newInstance方法或反射找出这个类的构造器。但是,不能实例化一个接口,需要在程序处于运行状态时定义一个新类。

代理机制解决的问题:

(1)路由对远程服务器的方法调用。

(2)在程序运行期间,将用户接口事件与动作关联起来。

(3)为调试,跟踪方法调用。

代理类一旦被创建,就变成了常规类,与虚拟机中的任何其他类没有什么区别。

所有的代理类都扩展于Proxy类。一个代理类只有一个实例域——调用处理器,它定义在Proxy的超类中。为了履行代理对象职责,所需要的任何附加数据都必须存储在调用处理器中。

没有义代理类的名字,Sun虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名。

对于特定的类加载器和预设的一组接口来说,只能有一个代理类。也就是说, 如果使用同一个类加载器和接口数组调用两次newInstance方法的话,那么只能得到同一个类的两个对象。也可以利用getProxyClass方法获得这个类:

Class proxyClass = Proxy.getProxyClass(null, interfacees);


代理类一定是public和final。如果代理类实现的所有接口都是public,代理类就不属于某个特定的包;否则,所有非公有的接口都必须属于同一个包,同时,代理类也属于这个包。

可以通过Proxy类中的isProxyClass方法检测一个特定的Class对象是否代码一个代理类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: