zoukankan      html  css  js  c++  java
  • 内部类

    内部类:

    package innerClass;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Date;
    
    /**
     * Created by admin on 2017-3-29.
     */
    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);
        }
    
    }
    class TalkingClock{
        private int interval;
        private boolean beep;
    
        public TalkingClock(int interval, boolean beep) {
            this.interval = interval;
            this.beep = beep;
        }
    
        public void start(){
            ActionListener listener = new TimePrinter();
            Timer t = new Timer(interval,listener);
            t.start();
        }
    class TimePrinter implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(new Date());
            if (beep){
                System.out.println("beep");
            }
        }
    }
    
    }

    非内部类:

    package innerClass;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Date;
    
    /**
     * Created by admin on 2017-3-29.
     */
    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);
        }
    
    }
    class TalkingClock{
        private int interval;
        private boolean beep;
    
        public TalkingClock(int interval, boolean beep) {
            this.interval = interval;
            this.beep = beep;
        }
    
        static boolean access$000(TalkingClock talkingClock){
            return talkingClock.beep;
        }
        public void start(){
            ActionListener listener = new TimePrinter(this);
            Timer t = new Timer(interval,listener);
            t.start();
        }
    
    }
    class TimePrinter implements ActionListener{
    
        private TalkingClock outer;
    
        public TimePrinter(TalkingClock clock) {
            outer = clock;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(new Date());
            if (TalkingClock.access$000(outer)){
                System.out.println("beep");
            }
        }
    }

    1.内部类可以访问该类定义所在作用域中数据,包括私有。是因为内部类的对象有一个隐式引用,他指向了创建它的外部类对象。外部类的引用在构造器中设置,构造器的参数为外部类引用。
    2.内部类一种编译器现象,与虚拟机无关。编译器会把内部类翻译成用$(美元符号)分隔外部类名与内部类名的常规文件。编译器为了引用外部类,会生成一个附加的实例域this$0(名字是有编译器合成的,在自己的代码中不能引用它)。

    3.内部类被翻译成名字怪异的常规类,对于域来说,每个域会自动生成一个静态方法access$000(或access$0),该方法接受所属类对象为参数,返回值传给域。可以利用这个在B类中调用A类的私有方法。

    局部内部类:

    package innerClass;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Date;
    
    /**
     * Created by admin on 2017-3-29.
     */
    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);
        }
    
    }
    class TalkingClock{
        private int interval;
        private boolean beep;
    
        public TalkingClock(int interval, boolean beep) {
            this.interval = interval;
            this.beep = beep;
        }
    
        public void start(){
    
            class TimePrinter implements ActionListener{
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(new Date());
                    if (beep){
                        System.out.println("beep");
                    }
                }
            }
    
            ActionListener listener = new TimePrinter();
            Timer t = new Timer(interval,listener);
            t.start();
        }
    
    
    }

    局部内部类不能用public或private访问说明符进行说明。它的作用域被限定在声明这个局部类的块中。优势:仅仅start方法指导该局部内部类的存在。

    从外部方法访问变量:

    package innerClass;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Date;
    
    /**
     * Created by admin on 2017-3-29.
     */
    public class InnerClassTest {
    
        public static void main(String[] args) {
            TalkingClock clock = new TalkingClock();
            clock.start(1000,true);
            JOptionPane.showMessageDialog(null,"Quit program?");
            System.exit(0);
        }
    
    }
    class TalkingClock{
    
        public void start(int interval,final boolean beep){
    
            class TimePrinter implements ActionListener{
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(new Date());
                    if (beep){
                        System.out.println("beep");
                    }
                }
            }
    
            ActionListener listener = new TimePrinter();
            Timer t = new Timer(interval,listener);
            t.start();
        }
    
    
    }

    不仅能够访问包含他们的外部类,还可以访问局部变量。不过。局部变量必须被声明为final。(如果不设为final的话,start方法结束后,beep参数变量不复存在)。
    实际上,当创建一个局部内部类对象时,ceep会被传递给构造器,并存储在val$beep域中。编译器必须检测对局部变量的访问,为每一个变量建立相应的数据域,并将局部变量拷贝到构造器中,以便将这些数据初始化为局部变量的副本(只有在构造器中调用一次,所以局部变量必须是final,不可改变的,否则很容易就不一致了)。但是有时会想要改变参数,比如计数器,考虑必须是final的,也必须是可以改变值的,所以用到了数组,final代表数组的对象不变,但是里面的只可以改变。

    匿名内部类:

    package innerClass;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Date;
    
    /**
     * Created by admin on 2017-3-29.
     */
    public class InnerClassTest {
    
        public static void main(String[] args) {
            TalkingClock clock = new TalkingClock();
            clock.start(1000,true);
            JOptionPane.showMessageDialog(null,"Quit program?");
            System.exit(0);
        }
    
    }
    class TalkingClock{
    
        public void start(int interval,final boolean beep){
    
            Timer t = new Timer(interval, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(new Date());
                    if (beep){
                        System.out.println("beep");
                    }
                }
            });
            t.start();
        }
    
    
    }

    匿名内部类在jdk1.8中可以用lambda表达式来代替。
    注:::t.invaite(new ArrayList<String>(){{ add.("Harry"); add("Tony");}})。双大括号初始化:外层:ArrayList的匿名类,内层:对象构造块。

    静态内部类:

    package innerClass;
    
    /**
     * Created by lyj on 2017-3-30.
     */
    public class ArrayAlg {
    
    
        public static void main(String[] args) {
            double[] a = new double[10];
            for(int i=0;i<a.length;i++){
                a[i] = Math.random()*100;//0-100
            }
            Pair pair = ArrayAlg.minmax(a);
            System.out.println(pair.getFirst());
            System.out.println(pair.getSecond());
        }
        public static Pair minmax(double[] values){
            double max = Double.MIN_VALUE;
            double min = Double.MAX_VALUE;
            for (double v : values) {
                if(min > v){
                    min = v;
                }
                if(max < v){
                    max = v;
                }
            }
            System.out.println(min);
            System.out.println(max);
            return new ArrayAlg.Pair(min,max);
        }
        public static class Pair{
            private double first;
            private double second;
    
            public Pair(double first, double second) {
                this.first = first;
                this.second = second;
            }
    
            public double getFirst() {
                return first;
            }
    
            public double getSecond() {
                return second;
            }
        }
    }

    静态内部类的对象除了没有对生成它的外部类对象的引用特权之外,与其他所有内部类完全一样。在内部类不需要访问外部类对象时,应该使用静态内部类。

    注:::生命在接口中的内部类自动成为static和public类。

  • 相关阅读:
    第二阶段冲刺进程2
    第二阶段冲刺进程1
    Alpha版使用说明
    回复每组的意见的评价
    每个组针对本组提出的意见的整理
    软件项目第一次Sprint总结
    站立会议7
    站立会议6
    团队博客11
    团队博客10
  • 原文地址:https://www.cnblogs.com/wongem/p/6644402.html
Copyright © 2011-2022 走看看