(六)接口与内部类
1. 接口:
- 在Java中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。
- 接口中的方法自动的属于public,因此在接口中声明方法时,不必提供关键字public
- 接口中可以定义常量,但是绝对不能含有实例域,也不能在在接口中实现方法
- 接口中的常量被自动设定为public static final 类型
- 提供实例域和方法实现的任务应该由实现接口的那个类来完成
2. 将一个类实现某个接口,需要:
- 将类声明为实现给定的接口
- 对接口中的所有方法进行定义,而且需要将多有方法定义为public
3. 在比较两个对象的大小是,使用整数域进行比较比较巧妙,大于返回1,小于返回-1,相等返回0,但是对于浮点类型的比较不一定,因为即使可能不相等,但是四舍五入之后最终结果也可能相等。
4. 实现接口的好处:Java程序设计语言是一种强类型语言,在调用方法的时候,编译器将会检查这个方法是否存在,但是每个实现接口的类必须提供这个方法。
5. 例子。Employee 类实现了Comparable接口,因此可以调用Array.sort();方法对Employee数组进行排序
- 
public class Employee implements Comparable<Employee>{ private String name; private double salary; public Employee(){ } public Employee(String name, double salary){ this.name = name; this.salary = salary; } public void setName(String name){ this.name = name; } public void setSalary(double salary){ this.salary = salary; } public String getName(){ return this.name; } public double getSalary(){ return this.salary; } public int compareTo(Employee other){ return Double.compare(this.salary,other.salary); } public static void main(String[] args) { } }import java.util.*; public class Test{ public static void main(String[] args) { Employee[] staff = new Employee[3]; staff[0] = new Employee("zhang san",5000); staff[1] = new Employee("lisi",3000); staff[2] = new Employee("wangwu",6000); Arrays.sort(staff); for (Employee e : staff) { System.out.println("name= " + e.getName() + " salary= " + e.getSalary()); } } } 
6. 接口的一些特性:
- 接口不是类,尤其不能使用new运算符实例化一个接口
- 可以声明接口变量Comparable x = new Employee();//Employee类实现了接口Comparable。
- 与检查一个对象是否属于一个特定的类一样,也可以使用instanceof检查一个对象是否是实现了某个接口if(object instanceof Comparable)
- 接口也可以被其他接口继承扩展
7. 每个类只能够拥有一个超类,但是却可以实现多个接口。也就是所谓的单继承多实现,使用,号将需要实现的的多个接口分隔开,需要有克隆功能实现Cloneable接口,需要有比较功能实现Comparable接口 public class Employee implements Cloneable,Comparable{}
8. 为什么不将interface接口直接声明为abstract抽象类,子类继承的时候也就必须实现其中的抽象方法了?
- 每个类只能扩展于一个类
- 但是每个类可以实现多个接口
- Java的设计者选择了不支持多继承,其主要原因是多继承会让语言本身变得非常复杂,效率也会降低
- 使用接口的方式可以提供多继承的大多数好处,同时还能避免多继承的复杂性和低效性
9. 接口与回调:需要实现ActionListener接口,然后需要执行的语句放在actionPerformed方法中,下面是示例代码,通过定时器调用监听器对象,执行其中的方法
- 
public class TimerPrint implements ActionListener{ public void actionPerformed(ActionEvent event){ Date now = new Date(); System.out.println("At the tone, the time is:"+now); Toolkit.getDefaultToolkit().beep(); } }public class Test{ public static void main(String[] args) { ActionListener listener = new TimerPrint(); Timer t = new Timer(5000,listener); t.start(); JOptionPane.showMessageDialog(null,"Quit program"); System.exit(0); } }
10. 内部类:定义在另一个类中的类
- 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据
- 内部类可以对同一个包中的其他类隐藏起来
- 当想用定义一个回掉函数且不想编写大量代码时,使用匿名内部类比较便捷
- 内部类既可以访问自身的数据域,也可以访问创建他的外围类对象的数据
- 
public class InnerClassTest{ public static void main(String[] args) { TalkingClock clock = new TalkingClock(5000,false); clock.start(); JOptionPane.showMessageDialog(null,"Quit program"); System.exit(0); } class TalkingClock{ private int internal; private boolean beep; public TalkingClock(int internal,boolean beep){ this.internal = internal; this.beep = beep; } public void start(){ ActionListener listener = new TimerPrint(); Timer t = new Timer(internal,listener); t.start(); } public class TimerPrint implements ActionListener{ public void actionPerformed(ActionEvent event){ Date now = new Date(); System.out.println("At the tone, time is :"+now); if(beep) Toolkit.getDefaultToolkit().beep(); beep = !beep; } } } }如果一个内部类只在创建对象的时候用了一次,那么可以在一个方法中定义局部类 
- 局部类不能使用public或者private访问说明符进行声明,他的作用域被限定在声明这个局部类的块中
- 局部类有一个优势,即对外部世界可以完全的隐蔽起来。即使TalkingClock类中的其他代码也不能访问他
- 除了start方法之外,没有任何方法知道TimerPrint类的存在
- 
public void start(){ class TimerPrint implements ActionListener{ public void actionPerformed(ActionEvent event){ Date now = new Date(); System.out.println("At the tone, time is :"+now); if(beep) Toolkit.getDefaultToolkit().beep(); beep = !beep; } } ActionListener listener = new TimerPrint(); Timer t = new Timer(internal,listener); t.start(); }
11. 匿名内部类:将局部内部类的使用再深入一点,假如只创建这个类的对象,就不必命名了。这种类称为匿名内部类。
- 
public void start(){ ActionListener listener = new ActionListener(){ public void actionPerformed(ActionEvent event){ Date now = new Date(); System.out.println("At the tone, time is :"+now); if(beep) Toolkit.getDefaultToolkit().beep(); beep = !beep; } }; Timer t = new Timer(internal,listener); t.start(); }
    http://www.cnblogs.com/makexu/

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号