java内部类的理解

在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,则可带参数。

你可能感兴趣的:(java内部类的理解)