博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java——内部类(inner class)
阅读量:6267 次
发布时间:2019-06-22

本文共 5337 字,大约阅读时间需要 17 分钟。

为什么要使用内部类?

主要因为以下三点:

1、内部类方法可以访问该类定义所在的作用域的数据,包括私有数据。
2、内部类可以对同一个包中的其他类隐藏起来。
3、想要定义一个回调函数却不想编写大量代码,使用匿名内部类比较便捷。
 

一个类的定义放在另一个类的内部,这个类就叫做内部类。 (类名不需要和文件夹相同)

public class Inner {    //像这样的,Contents就叫做内部类         public class Contents {        public void f() {            System.out.println("hello");        }    }}

内部类可以是静态static的,也可用public,default,protected和private修饰。而外部类(类名和文件名相同的类)只能使用public和default来修饰。

内部类是一种编译器现象,与虚拟机无关。编译器将会把内部类编译成用$分隔外部类名与内部类名的常规类文件,而虚拟机对此一无所知。
例如:对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。

 

内部类分为以下四种:      

静态内部类static inner class (also called nested class)

成员内部类member inner class

局部内部类local inner class

匿名内部类anonymous inner class

 

静态内部类Static Inner Class

1、最简单的内部类形式。

2、类定义时加上static关键字。

3、不能和外部类有相同的名字。

4、只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。

5、生成静态内部类对象的方式为:

  OuterClass.InnerClass inner = new OuterClass.InnerClass();

 
package cy.内部类.静态内部类;public class StaticOuter {    private static String name = "Outer";    private int age = 10;    public static class StaticInner {        @SuppressWarnings("unused")        private static String name = "Inner";        public void sayOuterName() {            System.out.println("inner:" + StaticOuter.name);        }                /*         * 错误,静态内部类不能访问外部类的非静态成员。            public void sayOuterAge() {                System.out.println(age);            }         */    }    public void sayName() {        System.out.println(name);    }    public void sayAge() {        System.out.println(age);    }}
package cy.内部类.静态内部类;public class TestMain {    public static void main(String[] args) {        StaticOuter staticOuter = new StaticOuter();        staticOuter.sayAge();        staticOuter.sayName();                StaticOuter.StaticInner staticInner = new StaticOuter.StaticInner();        staticInner.sayOuterName();    }}

运行结果:

10

Outer
inner:Outer

由此可以看出,静态内部类的对象处了没有对外围类对象的应用特权外,与其他所有内部类完全一样。

 

成员内部类member inner class

package cy.内部类.成员内部类;public class Outer {    private static String name = "Outer";    private int age = 10;    public class Inner {        private final static String name = "Inner";        private int age = 11;                public void sayOuterName() {            // 内部类中引用外部类对象的静态成员            System.out.println("inner:" + Outer.name);        }                public void sayInnerName() {            System.out.println("inner:" + Inner.name);        }                public void sayInnerAge() {            System.out.println("inner:" + this.age);        }        public void sayOuterAge() {            // 内部类中引用外部类对象的非静态成员            System.out.println(Outer.this.age);        }                public Outer createOuter() {            // 内部类中创建外部类。            return new Outer();        }    }    public void sayName() {        System.out.println(name);    }    public void sayAge() {        System.out.println(age);    }    public Inner createInner() {        // 外部类中创建内部类对象。        return this.new Inner();    }    }
public class TestMain {    public static void main(String[] args) {        Outer outer = new Outer();        outer.sayAge();        outer.sayName();        // 区别于静态内部类的创建方法        Inner inner = outer.new Inner();        inner.sayOuterName();    }}

运行结果:

10

Outer
inner:Outer

 

局部内部类local inner class

局部类不能用public,protected或者private访问说明符进行声明。它的作用域是被限定在这个局部类的块中。

局部类有一个优势,即对外世界可以完全隐藏起来,其他类中的代码不能访问它。

package cy.内部类.局部内部类;public class Outer {    private static String name = "Outer";    private int age = 10;    public void doSomeThing() {        // 局部内部类,局部内部类,不允许带有 public,protected,private        // public class Inner {        // protected class Inner {        // private class Inner {
class Inner { // private static String name; // private final static String name; public void sayInnerName() { System.out.println(name); } public void sayOuterName() { System.out.println(Outer.name); } } Inner inner = new Inner(); inner.sayInnerName(); inner.sayOuterName(); } public void doSomeThingA() { if (this.age > 0) { // 这个Inner与上一个Inner没有任何关系 class Inner { public void sayInnerName() { System.out.println(name); } public void sayOuterName() { System.out.println(Outer.name); } } Inner inner = new Inner(); inner.sayInnerName(); inner.sayOuterName(); } } public void sayName() { System.out.println(name); } public void sayAge() { System.out.println(age); }}

 

匿名内部类anonymous inner class

假设这创建某个类的一个对象,就不必命名了,这种类成为“匿名内部类”。

package cy.内部类.匿名内部类;public class Outer {    public static void main(String[] args) {        // 内部类引用外部类对象,使用final。        final String name = "name";        // 接口直接创建对象。类名称并没有直接定义。Java编译器会自动给一个类名称。        // 注意匿名内部类的重要使用场景。“线程”        Say s = new Say() {            @Override            public void say() {                System.out.println("hello world " + name);            }        };        s.say();    }}interface Say {    void say();}

这种语法有点难理解,它的含义是:创建一个实现Say接口的类的新对象,需要实现的方法say定义在{}中。

由于构造器的名字必须跟类名相同,而匿名类没有名称,所以匿名类不能有构造器。取而代之的是,构造器参数传递给超类(superclass)构造器。尤其是在内部类实现接口的时候,不能有任何构造参数。

转载于:https://www.cnblogs.com/iCcccy/p/4692227.html

你可能感兴趣的文章
Vue实例初始化的选项配置对象详解
查看>>
PLM产品技术的发展趋势 来源:e-works 作者:清软英泰 党伟升 罗先海 耿坤瑛
查看>>
vue part3.3 小案例ajax (axios) 及页面异步显示
查看>>
软件测试(二)之 Failure, Error & Fault
查看>>
浅谈MVC3自定义分页
查看>>
.net中ashx文件有什么用?功能有那些,一般用在什么情况下?
查看>>
select、poll、epoll之间的区别总结[整理]【转】
查看>>
CSS基础知识(上)
查看>>
PHP中常见的面试题2(附答案)
查看>>
角色权限分配
查看>>
明小子动力上传拿webshell.zip
查看>>
ES6 Module export与import复合使用
查看>>
第三篇、image 设置圆角的几种方式
查看>>
关于Vs2010 C#使用DirectX的问题
查看>>
EPP(Eclipse PHP)语法高亮仿EditPlus配置
查看>>
OA账号架构权限的问题
查看>>
030——VUE中鼠标语义修饰符
查看>>
python编辑csv
查看>>
sql游标的使用与exec的两种用法
查看>>
数据结构
查看>>