Java内部类


内部类简介


Java 一个类中能够嵌套另一个类,语法格式以下:html

class OuterClass {   // 外部类
    // ...
    class NestedClass { // 嵌套类,或称为内部类
        // ...
    }
}

嵌套类有以下几种类型:java

image


成员内部类


最简单的一种内部类,形式以下,跟其余变量同样,是一个类中的一个成员jvm

class Outer {
    
    String str = "hello";
     
    public Outer(String str) {
        this.str = str;
    }
    
    /* 内部类 */
    class Inner {     
        public void showStr() {
            System.out.println(str);
        }
    }
}

  • 成员内部类能够无条件地访问外部类的全部元素
  • 外部类访问内部类须要先建立一个内部类对象
  • 成员内部类是依附外部类而存在
能够访问外部类原理

编译器会在编译时生成外部类和内部类两个字节码文件,还会给内部类的无参构造函数增长一个参数,为外部类的一个应用,且指向了外部类,故能够随意使用外部类一切。函数

侧面说明成员内部类依赖于外部类的优先建立,否则会初始化失败this


局部内部类


定义在一个方法或者一个做用域里面的类,局部内部类的访问仅限于方法内或者该做用域内spa

class MyClass{
    public MyClass() {
         
    }
}
 
class Outer{
    public Outer(){
         
    }
     
    public MyClass getInner{
        
        /* 局部内部类 */
        class Inner extends MyClass{   
            int age = 0;
        }
        return new Inner();
    }
}

局部内部类就像是方法里面的一个局部变量同样,是不能有 public、protected、private 以及 static 修饰符的线程


匿名内部类


先看一下官方给的例子code

public class HelloWorldAnonymousClasses {

    /**
     * 包含两个方法的HelloWorld接口
     */
    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {

        // 一、局部类EnglishGreeting实现了HelloWorld接口
        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }

        HelloWorld englishGreeting = new EnglishGreeting();

        // 二、匿名类实现HelloWorld接口
        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

        // 三、匿名类实现HelloWorld接口
        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo";
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };

        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }
}

匿名类表达式包含如下内部分:htm

  1. 操做符:new;
  2. 一个要实现的接口或要继承的类,案例一中的匿名类实现了HellowWorld接口,案例二中的匿名内部类继承了Animal父类;
  3. 一对括号,若是是匿名子类,与实例化普通类的语法相似,若是有构造参数,要带上构造参数;若是是实现一个接口,只须要一对空括号便可;
  4. 一段被"{}"括起来类声明主体;
  5. 末尾的";"号(由于匿名类的声明是一个表达式,是语句的一部分,所以要以分号结尾)。

本部分参考JAVA匿名内部类(Anonymous Classes)对象


静态内部类


静态内部类是不须要依赖于外部类的,而且它不能使用外部类的非static成员变量或者方法,这个和普通静态方法不能访问非静态方法或变量的原理同样,具体能够了解一下类的加载生命周期。

简单地说就是静态变量或方法是属于类的,非静态方法或变量是属于对象的,jvm加载类的时候就为类的静态变量或方法分配内存的,而非静态的须要等到要初始化对象时候才给分配内存,而这个过程是动态的,也就是等到咱们何时想用,才会有累的初始化过程。

简单举个例子:

class Outer {
	int a = 1
	static int a = 2;
    public Outter() {
         
    }
     
	/* 静态内部类 */
    static class Inner {
        public Inner() {
             System.out.println(a); // 编译会报错
             System.out.println(b);

        }
    }
}

使用:

public class Test {
    public static void main(String[] args)  {
        Outer.Inner inner = new Outer.Inner();
    }
}

内部类简单应用


为何在 Java 中须要内部类?总结一下主要有如下四点内部类的使用场景和好处:

  • 1.每一个内部类都能独立的继承一个接口的实现,因此不管外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
  • 2.方便将存在必定逻辑关系的类组织在一块儿,又能够对外界隐藏。
  • 3.方便编写事件驱动程序。
  • 4.方便编写线程代码。
相关文章
相关标签/搜索