一、接口与抽象类的区别:
1、一个类可以实现多个接口,只能继承一个类;
2、抽象类可以包含具体的方法,接口的方法都是抽象的;
3、抽象类可以声明和使用字段;接口不能,接口只能有static final常量
4、抽象类可以是public、protected、private或者默认的package,而接口全为public
5、抽象类可以定义构造函数,接口不能。
接口描述了类协作中它所期望与不期望的行为。工程师设计了很多火箭,有固体燃料火箭也有液体燃料火箭,不能火箭如何组成,但是对火箭仿真必须提供预期的推理、质量等数据。
public interface RocketSim{
abstract double getMass();
public double getThrust();
void setSimTime(double t);
}
接口的声明public不应该省略,否则接口的可见性限制在包内。三个方法都是abstract public的。接口可以扩展。接口中可以定义常量,实现该接口的类可以访问它。
二、适配器(Adapter)
其作用是将一个类的接口,变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够一起工作。
适配器模式包含两种,一种是类适配器,另一种是对象适配器。类适配器是通过类的继承实现的适配,而对象适配器是通过对象间的关联关系,组合关系实现的适配。
适配器模式是一种补救模式,不管之前的可行性分析、需求分析、系统设计处理的多么完美,总会出现一些“意外”。适配器模式最好在设计阶段不要考虑它,它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题。
NewClass继承ExistingClass,实现接口RequiredInterface。NewClass中重写的requiredMethod方法
委托给ExistingClass的usefulMethod实现。
public interface Weather {
void show(); //显示天气
}
public class TodayWeather {
private int[] data;
public TodayWeather(int data[]){
this.data=data;
}
void showWeather(int time){
//...根据data来计算时间time的天气
}
}
已经有两个类,现在想显示当前天气,可以如下做:
public class CurrentWeather extends TodayWeather implements Weather{
private int time=0;
public CurrentWeather(int[] data) {
super(data);
}
public void setTime(int time){
this.time=time;
}
@Override
public void show(){
if(time>0&&time<24)
showWeather(time);
}
}
以上是类适配器,下面是一个对象适配器的例子:
public class Weather {
private String s;
private int t;
public Weather(){s=null;t=0;}
public Weather(String s,int t ){
this.s=s;this.t=t;
}
public void setTime(int time){
this.t=time;
}
public int getTime(){
return t;
}
void show(){
System.out.println("Time:"+t+";Weather:"+s);
};
}
public class CurrentWeather extends Weather{
private TodayWeather todayWeather;
public CurrentWeather(TodayWeather todayWeather){
this.todayWeather=todayWeather;
}
@Override
public void show(){
todayWeather.showWeather(super.getTime());
}
}
类的适配器继承现有的类并且实现目标接口;对象适配器继承目标类同时引用现有的类。
JTable可以用表格的形式显示TableMode型的“数据”。那么要想显示自己的数据,可以构造一个类继承TableModel,这个类中引用现有的数据。
public class Student {
private String name;
private int age;
private int score;
public Student(String name,int age,int score){
this.name=name;
this.age=age;
this.score=score;
}
public String getName(){return name;}
public int getAge(){return age;}
public int getScore(){return score;}
}
接下来是一个适配器类,它是Student与JTable之间的桥梁:
import javax.swing.table.AbstractTableModel;
public class StudentTableModel extends AbstractTableModel{
private Student[] student;
private String[] columns={"姓名","年龄","分数"};
public StudentTableModel(Student[] student){
this.student=student;
}
@Override
public int getColumnCount() {
return columns.length;
}
@Override
public int getRowCount() {
return student.length;
}
@Override
public String getColumnName(int i){
return columns[i];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch(columnIndex){
case 0:return student[rowIndex].getName();
case 1:return student[rowIndex].getAge();
case 2:return student[rowIndex].getScore();
default:return null;
}
}
}
下面是显示:JTable中传递了个参数是StudentTableModel类型的
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
public class ShowStudents {
public static void main(String[] args){
setFonts();
JTable table=new JTable(setStudentTableModel());
table.setRowHeight(36);
JScrollPane pane=new JScrollPane(table);
pane.setPreferredSize(new Dimension(300,100));
display(pane,"sheet");
}
private static void display(JScrollPane pane,String s){
JFrame frame=new JFrame(s);
frame.getContentPane().add(pane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static StudentTableModel setStudentTableModel(){
Student s1=new Student("王小二",18,80);
Student s2=new Student("赵武",19,83);
return new StudentTableModel(new Student[]{s1,s2});
}
private static void setFonts(){
Font font=new Font("Dialog",Font.PLAIN,18);
UIManager.put("Table.font", font);
UIManager.put("Table.font", font);
UIManager.put("TableHeader.font", font);
}
}
运行结果;