第6章 接口和内部类

来源:互联网 发布:淘宝卖家怎么赚淘金币 编辑:程序博客网 时间:2024/05/19 03:42

1.接口

一个类可以实现一个或多个接口。
接口中的所有方法自动属于public。
接口绝不能含有实例域,也不能在接口中实现方法。
实现接口的步骤:
1)将类声明为实现给定的接口 关键字implements
2)对接口中的所有方法进行定义
警告在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问属性,之后编译器就会给出试图提供更严格的访问权限的警告信息。

提示:Comparable接口中的compareTo方法将返回一个整数值,两个对象相等将返回0,前者大,返回正值,否则返回负值。
调用Arrays类中的sort方法时,必须使用实现Comparable接口的数组作为sort方法的参数。
当子类重写超类compareTo方法时,比较时注意类型检测。
if(getClass()!=other.getClass()) throw new ClassCastException();
如果存在通用算法能够对两个不同的子类对象进行比较,则应该在超类中提供一个compareTo方法,并将这个方法声明为final。

1.1 接口的特性

接口不是类,不能用new运算符实例化一个接口,可以声明接口的变量。
可以用instanceof检查一个对象是否实现了某个特定的接口。
接口可以扩展。
接口中不能包含实例域和静态方法,但可以包含常量。接口中的域自动声明为public static final。
每个类只能继承一个超类,但可以实现多个接口。

1.2 接口与抽象类

Java不支持多继承,原因是多继承会让语言本身变得非常复杂(C++),效率也会降低(Eiffel)。
深入理解Java接口和抽象类

2.对象克隆

Object.clone()     //访问权限是protected
默认的克隆操作是浅拷贝,他并没有拷贝包含在对象中的内部对象。
更常见的情况是子对象可变,因此,必须重新定义clone方法,以便实现克隆子对象的深拷贝。
对于每一个类,都需要做出下列判断:
1.默认的clone方法是否满足需求
2.默认的clone方法是否能够通过调用可变子对象的clone得到修补
3.是否不应该使用clone
实际上,选项3是默认的。如果选择1或2,类必须:
1.实现Cloneable接口
2.使用 public 访问修饰符重新定义clone方法。
即使clone的默认实现(浅拷贝)能够满足需求,也应该实现Cloneable接口,将clone重定义为 public,并调用super.clone()。
class Employee implements Cloneable  {      // raise visibility level to public, change return type      public Employee clone() throws CloneNotSupportedException      {          return (Employee)super.clone();      }  }  

深拷贝
class Employee implements Cloneable  {      ...      public Employee clone() throws CloneNotSupportedException      {          // call Object.clone()          Employee cloned = (Employee)super.clone();          // clone mutable fields          clone.hireDay = (Date)hireDay.clone();          return cloned;      }  }  
所有的数组类型均包含一个clone方法,这个方法被设为 public,而不是 protected,可以利用这个方法创建一个包含所有数据元素拷贝的一个新数组。
int[] luckyNumbers = {2, 4, 5};  int[] cloned = luckyNumbers.clone();  cloned[1] = 8;      // don't change luckyNumbers[1]  

3.内部类

内部类是定义在另一个类中的类。使用内部类的原因:
·内部类方法可以访问该类定义所在作用域中的数据,包括私有的数据
·内部类可以对同一个包中的其他类隐藏起来
·当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
内部类的对象有一个隐式引用(OuterClass.this),它引用了实例化该内部对象的外围类对象。通过这个指针,可以访问外围类对象的全部状态。
引用内部类:OuterClass.InnerClass
匿名内部类:
public void start(int interval, final boolean beep)  {      ActionListener listener = new ActionListener()      {          public void actionPerformed(ActionEvent event)          {              Date now = new Date();              System.out.println("At the tone, the time is " + now);              if (beep)                  Toolkit.getDefaultToolkit().beep();          }      };      Timer t = new Timer(interval, listener);      t.start();  }     


原创粉丝点击