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)为了履行代理对象的职责,任何所需的附加数据都要存储在调用处理器中。

posted @ 2021-05-17 21:41  Xiarsu  阅读(127)  评论(0)    收藏  举报