关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »Java 内部类的一些整理

    Java 内部类的一些整理

    2015-12-07 00:00:00 出处:Java译站
    分享

    作为刚入门Java的小白,这两天看到内部类,这里做一个总结,若有错误,欢迎指正~

    内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。

    内部类分为: 成员内部类、局部内部类 、 静态嵌套类 、匿名内部类 。

    1.成员内部类

    成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:

    class Outter {
        private int age = 12;
    
        class Inner {
            private int age = 13;
            public void print() {
                int age = 14;
                System.out.println("局部变量:" + age);
                System.out.println("内部类变量:" + this.age);
                System.out.println("外部类变量:" + Out.this.age);
            }
        }
    }
    
    public class test1 {
        public static void main(String[] args) {
            Outter out = new Outter();
            Outter.Inner in = out.new Inner();
            in.print();
        }
    }

    运行结果:

    局部变量:14
    内部类变量:13
    外部类变量:12

    从本例可以看出:成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法, 即使是private的 。虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:

    class Outter {
        private int age = 12;
        public Outter(int age) {
            this.age = age;
            getInInstance().print();   //必须先创建成员内部类的对象,再进行访问!
        }
    
        private Inner getInInstance() {
            return new Inner();
        } 
        class Inner {
            public void print() {
                System.out.println("内部类没同名,所以直接调用外部类成员变量:" + age);
            }
        }
    }
    
    public class test1 {
        public static void main(String[] args) {
            Outter out = new Outter(10);
        }
    }

    运行结果:

    内部类没同名,所以直接调用外部类成员变量:10
    内部类可以拥有 private访问权限、protected访问权限、public访问权限及包访问权限 。

    比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问; 如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。

    这一点和外部类有一点不一样, 外部类只能被public和包访问两种权限修饰 。

    我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。要注意的是,成员内部类不能含有static的变量和方法。 因为成员内部类需要先创建了外部类,才能创建它自己的

    2.局部内部类

    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

    定义在方法里的内部类:

    class Outter {
    
      private int age = 12;
    
        public void Print(final int x) {	//这里局部变量x必须设置为final类型!
            class Inner {
                public void inPrint() {
                    System.out.println(x);
                    System.out.println(age);
                }
            }
            new Inner().inPrint();
        }
    
    }
    
    public class test1 {
        public static void main(String[] args) {
            Outter out = new Outter();
            out.Print(10);
        }
    }

    运行结果:

    10
    12

    本例中我们将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方法。如果此时我们需要往外部类的方法中传入参数,那么外部类的方法形参必须使用 final 定义。

    换句话说,在方法中定义的内部类只能访问方法中final类型的局部变量,这是因为在方法中定义的局部变量相当于一个常量,它的生命周期超出方法运行的生命周期,由于局部变量被设置为final,所以不能再内部类中改变局部变量的值。(这里看到网上有不同的解释,还没有彻底搞清楚==)

    定义在作用域内的内部类:

    class Outter {
      private int age = 12;
      public void Print(final boolean x) {	//这里局部变量x必须设置为final类型!
        	if(x){
        		 class Inner {
        	            public void inPrint() {
        	                System.out.println(age);
        	            }
        	        }
        		 new Inner().inPrint();
        	}       
        }
    }
    
    public class test1 {
        public static void main(String[] args) {
            Outter out = new Outter();
            out.Print(true);
        }
    }

    运行结果: 12

    3.静态嵌套类

    又叫静态局部类、嵌套内部类,就是修饰为static的内部类。声明为static的内部类,不需要内部类对象和外部类对象之间的联系,就是说我们可以 直接引用outer.inner ,即不需要创建外部类,也不需要创建内部类。

    class Outter {
      private static int age = 12;
      static class Inner {
            public void print() {
                System.out.println(age);
            }
        }
    }
    
    public class test1 {
        public static void main(String[] args) {
        	Outter.Inner in = new Outter.Inner();
            in.print();
        }
    }

    运行结果:

    12

    可以看到,如果用static 将内部内静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性。

    其次,因为内部类被静态化,因此Outter.Inner可以当做一个整体看,可以直接new 出内部类的对象( 通过类名访问static,生不生成外部类对象都没关系 )

    4.匿名内部类

    匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段Android事件监听代码:

    scan_bt.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
    
                }
            });
    
            history_bt.setOnClickListener(new OnClickListener() {       
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
    
                }
            });

    这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。具体位置是这段:

    new OnClickListener() {   
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
    
                }
            }

    代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。当然像下面这种写法也是可以的,跟上面使用匿名内部类达到效果相同:

    private void setListener()
    {
        scan_bt.setOnClickListener(new Listener1());       
        history_bt.setOnClickListener(new Listener2());
    }
    
    class Listener1 implements View.OnClickListener{
        @Override
        public void onClick(View v) {
        // TODO Auto-generated method stub
    
        }
    }
    
    class Listener2 implements View.OnClickListener{
        @Override
        public void onClick(View v) {
        // TODO Auto-generated method stub
    
        }
    }

    这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的, 匿名内部类也是不能有访问修饰符和static修饰符的 。

    匿名内部类是唯一一种没有构造器的类 。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于 接口回调 。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    抖音安全与信任开放日:揭秘推荐算法,告别单一标签依赖

    ultraedit编辑器打开文件时,总是提示是否转换为DOS格式,如何关闭?

    Cornell大神Kleinberg的经典教材《算法设计》是最好入门的算法教材

    从 Microsoft 下载中心安装 Windows 7 SP1 和 Windows Server 2008 R2 SP1 之前要执行的步骤

    Llama 2基于UCloud UK8S的创新应用

    火山引擎DataTester:如何使用A/B测试优化全域营销效果

    腾讯云、移动云继阿里云降价后宣布大幅度降价

    字节跳动数据平台论文被ICDE2023国际顶会收录,将通过火山引擎开放相关成果

    这个话题被围观超10000次,火山引擎VeDI如此解答

    误删库怎么办?火山引擎DataLeap“3招”守护数据安全

    IT头条

    平替CUDA!摩尔线程发布MUSA 4性能分析工具

    00:43

    三起案件揭开侵犯个人信息犯罪的黑灰产业链

    13:59

    百度三年开放2.1万实习岗,全力培育AI领域未来领袖

    00:36

    工信部:一季度,电信业务总量同比增长7.7%,业务收入累计完成4469亿元

    23:42

    Gartner:2024年全球半导体营收6559亿美元,AI助力英伟达首登榜首

    18:04

    技术热点

    iOS 8 中如何集成 Touch ID 功能

    windows7系统中鼠标滑轮键(中键)的快捷应用

    MySQL数据库的23个特别注意的安全事项

    Kruskal 最小生成树算法

    Ubuntu 14.10上安装新的字体图文教程

    Ubuntu14更新后无法进入系统卡在光标界面解怎么办?

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。