在java的code过程中,常会面对内部类的使用,在此根据自己理解,对内部类做一总结,方便学习。高手轻拍。
内部类顾名思义,就是定义在其它类内部的类,在这里内部类有两种区分:在其它类的内部;在其它类的方法的内部。
内部类使用主要基于以下三点:
1)通过内部类可以直接访问该类所定义的作用域中的数据,包括private数据。
2)通过添加private访问符或local inner class,将内部类对同一包中其它类隐藏起来。
3)定义回调函数。
一:inner class
格式
class A { class B { .... } }
例子:
import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.Timer; import static java.lang.System.out; public class InnerClassTest { public static void main(String[] args) { // TODO Auto-generated method stub TalkingClock clock = new TalkingClock(1000, true); clock.start(); TalkingClock.TimerPrinter t = clock.new TimerPrinter(); JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } } /** * descr:inner class * */ class TalkingClock { public TalkingClock(int interval, boolean beep) { this.interval = interval; this.beep = beep; } /** * descr:inner class. if the inner class with private, * */ public void start() { ActionListener listener = this.new TimerPrinter(); Timer t = new Timer(this.interval, listener); t.start(); /* TalkingClockII t = new TalkingClockII(); t.start(1000, true); */ } /** * descr:if inner class declared with private, the inner class is only used * by outter class. any class couldn't used it,even if it is in the same * package. * */ class TimerPrinter implements ActionListener { public TimerPrinter() { } public TimerPrinter(int interval, boolean beep) { this.beep = beep; } public void actionPerformed(ActionEvent ev) { Date now = new Date(); System.out.println("At the tone, the time is " + now); if (TalkingClock.this.beep) { Toolkit.getDefaultToolkit().beep(); } } private boolean beep; } private int interval; private boolean beep; }
可以看到TimerPrinter作为内部类。当access specifier为default时,TimerPrinter为包访问权限,为public时,为公共访问权限,但TimerPrinter要根据Outter类来决定是否可被外包函数访问。当为private时,只可被Outter访问。
二:local inner class
格式:
class A{ method(para1, para2,...) { class B{ ... } } }
例子:
/** * descr:local inner class. * */ class TalkingClockII { public TalkingClockII() { } public void start(int interval, final boolean beep) { /** * descr:local inner class are never declared with an access * specifier(private, public or default). * */ class TimerPrinterI implements ActionListener { public void actionPerformed(ActionEvent ae) { Date now = new Date(); out.println("At the tone, the time is " + now); if (beep) { Toolkit.getDefaultToolkit().beep(); } } } //local innner class only konwed in start method. //ActionListener listener = new TimerPrinterI(); //Timer t = new Timer(this.interval, listener); Timer t = new Timer(interval, new TimerPrinterI()); t.start(); } }
TimerPrinterI作为局部内部类,不能用private、public、protected等修饰符来生命,local inner class的作用域被限定到生命该局部类的块中,这样使得TimerPrinterI类完全对外界隐藏,只有包含它的start方法知道其存在,即使是Outter class TalkingClockI都不知道TimerPrinterI的存在。
三:匿名内部类
格式:
class A { method1() { class B = new B(para1, para2,...) { ... }; } method2() { interface C = new C() { .... }; } }
例子:
class TalkingClockIII { public void runImplements() { IWrite w = new IWrite() { public void write(boolean flag) { if (flag) { out.println("anonymous inner class."); } } }; w.write(true); } public void runExtends(boolean flag) { TestWrite t = new TestWrite(flag) { public void test() { out.println("flag is " + flag); } }; t.test(); } }
匿名内部类中,如果匿名类继承的是interface,则不可带参数;如果继承的是class,则可带参数。