其他分享
首页 > 其他分享> > 6.3内部类

6.3内部类

作者:互联网

6.3内部类

使用内部类的原因

1.内部类可以对同一个包的其他类隐藏。
2.内部类方法可以访问定义这个类作用域中的数据,包括原本私有的数据。

6.3.1使用内部类访问对象状态

内部类既可以访问自身的数据域,也可以访问创建它的外围类的数据,
这是因为内部类的对象总有一个隐式引用,它指向创建它的外部类对象。
// 外围类的引用在构造器中设置。
    //编译器修改了所有的内部类的构造器,添加一个外围类引用的参数。
    //因为TimePrinter内部类没有定义构造器,所以编译器为这个类生成了一个默认的构造器
            public TimePrinter(TalkingClock clock) {
                outer = clock;
           }
package innerClass;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;
import javax.swing.*;

public class InnerClassTest {
    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock(1000, true);
        clock.start();
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit(0);
    }

    /**
     * 定义一个内部类
     */
    static class TalkingClock {

        private int interval;
        private boolean beep;

        public TalkingClock(int interval, boolean beep) {
            this.interval = interval;
            this.beep = beep;
        }

        /**
         * start方法
         */
        public void start() {
            // 当在start方法中创建了TimePrinter
            // ActionListener listener = new TimePrinter(this);
            ActionListener listener = new TimePrinter();
            Timer timer = new Timer(interval, listener);
            timer.start();
        }

        /**
         * 定义内部类
         */
        public class TimePrinter implements ActionListener {
            // 外围类的引用在构造器中设置。
            //编译器修改了所有的内部类的构造器,添加一个外围类引用的参数。
            //因为TimePrinter内部类没有定义构造器,所以编译器为这个类生成了一个默认的构造器
/*            public TimePrinter(TalkingClock clock) {
                outer = clock;
            }*/
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("At the tone, the time is" + Instant.ofEpochMilli(e.getWhen()));
                //内部类既可以访问自身的数据域,也可以访问创建它的外围类的数据,
                //这是因为内部类的对象总有一个隐式引用,它指向创建它的外部类对象。
//                if(outer.beep){...}
                if (beep) {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
    }

}

6.3.2 内部类的特殊语法规则

1.使用外围类引用的正规语法
    OuterClass.this  表示外围类引用。例如:
    if (OuterClass.this.beep) {
        Toolkit.getDefaultToolkit().beep();
    }
2.编写内部对象的构造器
    outerObject.new.InnerClass(construction parameters)。例如:
    ActionListener listener = this.new TimePrinter();
最新构造的Time Printer对象的外围类引用被设置为创建内部类对象方法中的this引用。
    一般来说,this是多余的,但是这样可以通过显式地命名将外围类引用设置为其他对象。

6.3.3 内部类是否有用、必要、安全

6.3.4 匿名内部类

使用匿名内部类实现事件监听器和其他回调。如今最好用的还是lambda表达式

6.5代理

利用代理可以在运行时创建实现了一组给定接口的新类。

只有在编译时期无法确定需要实现哪个接口时才有必要使用代理。

标签:内部,TimePrinter,beep,6.3,引用,public
来源: https://blog.csdn.net/qq_41479053/article/details/121365844