Java内部类的理解

文章详细介绍了Java中的内部类,包括innerclass、局部内部类和匿名内部类的使用。内部类可以直接访问外部类的私有数据,提供了一种封装机制。文中通过实例展示了如何创建和使用这些内部类,强调了它们的访问权限和作用域特点。局部内部类只能在定义它的方法内使用,而匿名内部类通常用于简洁实现接口或父类的特定行为。
摘要由CSDN通过智能技术生成

在 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{
            ...
        }
    }
}

例子:

package ch06;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.Timer;

/**
 * @copyright 2023-2022
 * @package   ch06
 * @file      TalkingClock01.java
 * @date      2023-06-04 13:38
 * @author    qiao wei
 * @version   1.0
 * @brief     Local inner class. Local inner class is defined in method of Outer class, it is not
 *            allowed modifying the method parameter in local inner class.
 * @history
 */
public class TalkingClock01 {
    
    public TalkingClock01() {
        flag = false;
    }
    
    /**
     * @class   TalkingClock01
     * @date    2023-06-04 13:36
     * @author  qiao wei
     * @version 1.0
     * @brief   Start method
     * @param   interval Time interval.
     * @param   beep flag for voice.
     * @return  
     * @throws
     */
    public void start(int interval, boolean beep) {
        
        /**
         * @copyright 2023-2022
         * @package   ch06
         * @file      TalkingClock01.java
         * @date      2023-06-04 13:20
         * @author    qiao wei
         * @version   1.0
         * @brief     Local inner class. inner class is defined in method.
         * @history
         */
        class TimePrinter01 implements ActionListener {

            public TimePrinter01() {}

            @Override
            public void actionPerformed(ActionEvent event) {
                Date now = new Date();
                System.out.println("At the tone, the time is " + now);
                
                // Reset outer class field is allowed.
                flag = true;
                
                if (beep) {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
        
        ActionListener listener = new TimePrinter01();
        Timer timer = new Timer(interval, listener);
        
        /**
         * After the start function, the beep parameter is no longer exists while timer is always runing
         * if beep is true.
         */
        timer.start();
    }
    
    private boolean flag;
}

TimePrinter01作为局部内部类,不能用 private、public、protected 等修饰符来生命,local inner class 的作用域被限定到生命该局部类的块中,这样使得TimePrinter01类完全对外界隐藏,只有包含它的 start 方法知道其存在,即使是 Outter class TalkingClock01都不知道TimePrinter01的存在。

注意事项:局部内部类调用方法的参数时,不能修改参数值。调用外部类的实例变量时,可以修改变量值。匿名内部类同样要注意。

三:匿名内部类

格式:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值