内部类就是在类的内部定义的类,为什么需要使用内部类:
1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。
2. 对于同一个包中的其他类来说,内部类能够隐藏起来。
3.匿名内部类可以很方便的定义回调。
4.使用内部类可以非常方便的编写事件驱动程序
package edu.uestc.avatar;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import javax.swing.Timer;
public class Talking {
private boolean beep;
private int interval = 1000;
public Talking(boolean beep, int interval) {
this.beep = beep;
this.interval = interval;
}
public void start() {
TimerPrintActionListener listener = new TimerPrintActionListener();
Timer timer = new Timer(interval, listener);
timer.start();
}
/**
* TimerPrintActionListner位于Talking内部----内部类
*/
public class TimerPrintActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("注意,当前时间:" + LocalDateTime.now());
//内部类可以直接访问外部类的数据
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
}
内部类的特殊语法规则
内部类有一个外围类的引用,使用外围类的引用语法:OuterClass.this
public void actionPerformed(ActionEvent e) {
System.out.println("注意,当前时间:" + LocalDateTime.now());
if(Talking.this.beep) Toolkit.getDefaultToolkit().beep();
}
一 成员内部类:定义在类的内部,方法的外部,
A.特点:a.作为类的一个成员,有4个权限修饰符:public (default) protected private
b.作为一个类,可以用abstract、final修饰,也有构造器,也可以在类里定义属性、方 法
B.成员内部类的注意事项:
a.非静态成员内部类:
1)创建对象的方式:先有外部类的对象,再通过外部类对象调用内部类的构造器,格式: 外部类对象.new 内部类()
2)调内部类的属性,可以用"this."来指明;
调外部类的不同名属性,直接调用即可;
调外部类的同名属性:外部类的类名.this.同名属性:表示外部类的当前对象的属性
3)不能有静态的属性和方法
b.静态成员内部类:
1)创建对象的方式:调用构造器的方式:外部类类名.内部类()
2)可以有非静态的属性和方法
3)静态内部类只能调用外部类的静态属性、方法,不能调用外部类的非静态属性、方法
C.成员内部类的优势:成员内部类作为外部类的成员,可以直接访问外部类的私有属性。
package edu.uestc.avatar;
/**
* 只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围对象,可以把内部类声明为static的,以便取消产生的引用
* 查找数字中的最大值和最小值
* @author Adan
*
*/
public class ArrayAlg {
public static Pair getMinAndMax(int[] list) {
int min = list[0], max = list[0];
for(int i = 1; i < list.length; i++) {
if(min > list[i]) min = list[i];
if(max < list[i])max = list[i];
}
return new Pair(min, max);
}
public static class Pair{
private int min;
private int max;
public Pair(int min,int max) {
this.min = min;
this.max = max;
}
public int getMin() {
return min;
}
public int getMax() {
return max;
}
}
}
二 局部内部类:定义在方法的内部,对于局部内部类我们常常使用一个方法,得到一个接口实现类的对象。局部内部类的优势:通过方法非常方便的得到一个接口实现类的对象。
package edu.uestc.avatar;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import javax.swing.Timer;
import edu.uestc.avatar.Talking.TimerPrintActionListener;
/**
* 局部内部类
* 发现:前面的TimerPrintActionListener类只是在Talking类的start()方法内部使用,可以使用局部内部类
*
*/
public class LocalInnerClassTalking {
private boolean beep;
private int interval = 1000;
public LocalInnerClassTalking(boolean beep, int interval) {
this.beep = beep;
this.interval = interval;
}
public void start() {
class TimerPrintActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("注意,当前时间:" + LocalDateTime.now());
//内部类可以直接访问外部类的数据
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
TimerPrintActionListener listener = new TimerPrintActionListener();
Timer timer = new Timer(interval, listener);
timer.start();
}
}
注意:匿名内部类通过使用"new 接口(){}"的方式用其隐含实现一个接口或抽象类,实现的部分写在大括号内。
package edu.uestc.avatar;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import javax.swing.Timer;
public class AnonymousInnerClassTalking {
private int interval;
private boolean beep;
public AnonymousInnerClassTalking(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
public void start() {
//匿名内部类:new的是实现了ActionListener接口类的实例,该类没有名字
Timer timer = new Timer(interval, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("注意,当前时间:" + LocalDateTime.now());
//内部类可以直接访问外部类的数据
if(beep) Toolkit.getDefaultToolkit().beep();
}
});
timer.start();
}
}