一、抽象类
在谈接口之前,我们先看看抽象类。
- 为什么需要抽象类?
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。
类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。 - 什么是抽象类?
用abstract关键字来修饰一个类,这个类叫抽象类。
用abstract来修饰一个方法,该方法叫抽象方法。
Java语法描述为:
abstract class 类名{
abstract 返回值类型 方法名(参数列表);//抽象方法只能被声明,无方法体
}
- 抽象类的使用规则
①抽象类和抽象方法都要使用 abstract 关键字声明;
②若一个方法被声明为抽象的,那么这个类也必须声明为抽象的;
③一个抽象类中可有 0~n 个抽象方法,以及 0~n 个具体方法;
④抽象类不能实例化,抽象类是用来被继承的;
⑤抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,则仍为抽象类;
⑥Abstract不能修饰变量、代码块、构造函数;
⑦Abstract不能修饰私有方法、静态方法、final方法、final类;
二、接口
- 为什么要使用接口?
①接口的本质是契约,标准,规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。
②接口把方法的特征和方法的实现分隔开来。接口提供了一个公用的方法提供方,用来规定子类的行为。 - 什么是接口?
接口的定义:在Java编程语言中,接口是一个抽象类型,是抽象方法和常量值定义的集合,通常以interface来声明。
访问修饰符 interface 接口名 {
//声明变量
//抽象方法
}
- 接口的特点
①通过interface关键字来声明。
②所有成员变量都默认是public static final修饰(全局常量)。
③所有抽象方法都默认是由public abstract修饰。
④没有构造函数,不能实例化对象。
⑤支持多继承机制。
例如:比如,小学生、中学生可由学生类继承而来,篮球运动员、足球运动员可由运动员类继承而来。此外,他们都有学习的能力,所以可以把学习作为接口给他们去实现。
interface Study {
abstract void study();
}
class Student implements Study {
@Override
public void study() {
//学习知识的方法
}
//其他属性和方法...
}
class Athlete implements Study {
@Override
public void study() {
//学习运动的方法
}
//其他属性和方法...
}
三、一个特殊的接口:动作事件监听器
先简要介绍一下Swing的事件模型。在Swing的事件模型中,组件可以触发一个事件。每种事件由不同的类表示。当事件被触发时,它将被一个或多个“监听器”接收,监听器负责处理事件。所以,事件发生的地方可以与事件处理的地方分离开。
所谓的事件监听器,就是一个“实现特定类型的监听器接口”的类对象。所以我们要做的就是,先创建一个监听器对象,然后把它注册(添加)到触发事件的组件。这个注册(添加)动作是通过调用触发事件的组件的addXXXListener()方法来完成的,XXX表示监听器所监听的事件类型。所有时间处理逻辑都 将被只与监听器类的内部。所以要编写一个监听器类只需先实现相应接口再完善时间处理逻辑即可。
下面以JFrame的按钮触发事件来说明:
我们先写一个窗体,并给窗体加上按钮:
import javax.swing.JFrame;
import java.awt.FlowLayout;
import javax.swing.JButton;
public class EventTest extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
new EventTest();
}
public EventTest() {
setTitle("事件接口测试"); //设置窗体标题
setSize(300,200); //设置窗体大小(单位是像素)
setDefaultCloseOperation(EXIT_ON_CLOSE); //设置关闭按钮
FlowLayout fl = new FlowLayout(); //一种按钮的流式布局,使得按钮在窗体上端居中分布
setLayout(fl);
//添加按钮
JButton btn = new JButton("按钮1");
JButton btn1 = new JButton("按钮2");
add(btn);
add(btn1);
setVisible(true); //窗体可视化
}
}
这样运行就出现了窗体和按钮,但是点击按钮,什么也没有发生。
这时我们需要给按钮加上监听器了,写一个按钮的监听器:
import java.awt.event.*;
public class Listener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
String btnstr = e.getActionCommand(); //获取动作(按钮)的字符串
switch (btnstr) {
case "按钮1":
System.out.println("按钮1被点击了");
break;
case "按钮2":
System.out.println("按钮2被点击了");
break;
default:
break;
}
}
}
按钮事件对应的是ActionListener监听器接口。需要重写actionPerformed方法来实现事件触发(按钮被点击)会发生什么。
然后在窗体类中给按钮加上监听器了
import javax.swing.JFrame;
import java.awt.FlowLayout;
import javax.swing.JButton;
public class EventTest extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
new EventTest();
}
public EventTest() {
setTitle("事件接口测试"); //设置窗体标题
setSize(300,200); //设置窗体大小(单位是像素)
setDefaultCloseOperation(EXIT_ON_CLOSE); //设置关闭按钮
FlowLayout fl = new FlowLayout(); //一种按钮的流式布局,使得按钮在窗体上端居中分布
setLayout(fl);
//添加按钮
JButton btn = new JButton("按钮1");
JButton btn1 = new JButton("按钮2");
add(btn);
add(btn1);
Listener listener = new Listener();
//给按钮加上监听器
//被监听的按钮点击时由监听队列调用
btn.addActionListener(listener);
btn1.addActionListener(listener);
setVisible(true); //窗体可视化
}
}
这时我们再来看点击按钮的效果: