内部类

内部类

一种定义在类中的类,他们是嵌套关系。在编译成功时,会生成多个.class文件,分别是外部类.class外部类$内部类.class

内部类分四种:

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

1.定义

  • 成员内部类

    public class TalkingClock{
        private int interval;
        int radius = 0;
        public TalkingClock(int interval){
            this.interval = interval;
        }
        //内部类
        public class TimePrinter{
            int radius = 0;
            public void actionPerformed(){
                System.out.println(interval);//调用外部类interval成员
                System.out.println(TalkingClock.this.radius);//调用外部类radius成员
            }
        }
        public int getTimePrinterRadius(){
            return getTimePrinter.radius;
        }
        public int getTimePrinter(){
            return new TimePrinter();
        }
        
    }
    public class Test{
        public static void main(String[] args){
            TalkingClock clock = new TalkingClock();
            //通过TalkingClock对象来创建
            TalkingClock.TimePrinter inter01 = clock.new TimePrinter();
            //通过TalkingClock对象的getTimePrinter()方法
            TalkingClock.TimePrinter inter02 = clock.getTimePrinter();
        }
    }
    
    • TalkingClock称为外部类,TimePrinter则是内部类,TimePrinter可以直接调用外部类成员,无需创建外部类实例。TalkingClock.TimePrinter代表内部类引用
    • 成员内部类拥有和外部类同名的成员变量或者方法时,在默认情况下访问的是内部成员(就近原则),如要访问外部类的同名成员,则通过classtype.this.varclasstype.this.methods()形式进行访问
    • 外部类要访问内部类成员,则要通过内部类实例访问。如果其他类要创建内部TimePrinter类的对象,前提要有外部类TalkingClock的实例,通过外部类的实例去创建内部类实例
    • 内部类可以用的访问修饰符同类成员一样,可以被privateprotectedpublic等修饰。
  • 局部内部类

    public class TalkingClock{
        private int interval;
        int radius = 0;
        public Object getTimePrinter(){
            class TimePrinter{
                int age = 0;
            }
            return new TimePrinter();
        }
    }
    

    局部内部类定义在方法或者作用域里面的类。其访问仅限于方法内或者该作用域内,跟方法里的成员一样,不能用privateprotectedpublicstatic等修饰。

  • 匿名内部类

    public interface Apple{
        void go();
    }
    public class Work{
        int num = 0;
    }
    public class Test{
        public static void main(String[] args){
            //new Work().num 叫做匿名对象的使用,不把实例保存到变量中。
            System.out.println(new Work().num);
            //匿名内部类
            Apple apple = new Apple(){
                void go(){
                    System.out.print("实现Apple接口匿名内部类的go()方法!!");
                }
            };//注要这是一条语句要有结束标识';'
            apple.go();
        }
    }
    /*
    实现Apple接口匿名内部类的go()方法!!
    
    Process finished with exit code 0
    */
    
    • 匿名内部类是编程中使用最多的内部类。在实现父类或者接口中的方法情况下同时产生一个相应的对象,前提这个父类或接口要先存在才能这样用。匿名内部类没有构造器
    • 匿名对象,只使用一次的对象,不用去声明变量来保存该对象。
    • 一般使用匿名内部类的方法来编写事件监听代码。
    • 匿名内部类也是不能有访问修饰符和static修饰符的
  • 静态内部类

    public class TalkingClock{
        int interval;
        public TalkingClock(){}
        public TalkingClock(int interval){ this.interval = interval; }
        static class TimePrinter{
            public int getOutterInterVal(){
                //不能直接访间外部类非静态成员
                return new TalkingClock(10).interval;
            }
        }
    }
    public class BaseTest {
        public static void main(String[] args){
            TalkingClock.TimePrinter timePrinter = new TalkingClock.TimePrinter();
            System.out.println(timePrinter.getOutterInterVal());
        }
    }
    /*
    10
    
    Process finished with exit code 0
    */
    
    • 静态内部类定义在类中,被static修饰。其不需要依赖于外部类,和类的静态成员类似,不能直接使用外部类的非static成员。静态内部类有静态域和静态方法

    • 如果内部类不需要访问外部类对象时,优先使用静态内部类。

    • 内部类也可以在接口中定义,默认为staticpublic

2.总结

  1. 内部类对这个包下的其他类隐藏起来,使其他类无法直接访问。内部类也可以在接口中定义,默认为static public

  2. 编译器会默认为成员内部类添加了一个指向外部类对象的引用。虽然我们在定义的内部类时构造器是无参构造器,但编译器还是会默认添加一个参数,这个参数是指向外部类对象的引用,因此可以在成员内部类中随意访问外部类的成员

  3. 成员内部类,必须先产生外部类的实例化对象,才能产生内部类的实例化对象。而静态内部类不用产生外部类的实例化对象即可产生内部类的实例化对象。

    //创建静态内部类对象的一般形式
    Outter.Inner inner = new Outter.Inner();
    //创建成员内部类对象的一般形式
    Outter.Inner inner = outterType.new Ineer();
    
  4. 在内部类中访问与外部类相同名称的成员,this代表内部类引用对象,OutterName.this代表外部类引用对象(OutterNAme表示外部类名)。


posted @   hello_12153_98  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示