java内部类

来源:互联网 发布:网络安全工程师怎么考 编辑:程序博客网 时间:2024/05/22 16:34
内部类有成员内部类和局部内部类
1.顶层类只能处于public和private,而成员内部类能处于public,protected,default和private级别
2.成员内部类分为两种,实例内部类和静态内部类,一个不用static修饰,一个用static修饰
实例内部类的特点:
(1)创建内部类的实例时,外部类的实例必须已经存在
(2)实例内部类的实例自动持有外部类的实例的引用,内部类之所以可以访问外部类的成员,是因为当内部类的实例存在时,外部类的实例肯定也已经存在,内部类自动持有外部类的实例的引用
(3)外部类实例与内部类实例之间是一对多的关系,一个内部类实例只能引用一个外部类实例,而一个外部类实例对应零个或多个内部类实例。在外部类实例中不能直接访问内部类成员,必须通过内部类的实例去访问
(4)实例内部类中不能定义静态成员,而只能定义实例成员
(5)如果内部类与外部类包含同名的成员,那么在内部类中,this.成员名表示内部类的成员,而外部类名.this.成员名表示外部类的成员
public class Outer {
    private int a;
    public Outer(int a)
    {
        this.a = a;
    }
    public class Inner{
        public int a;
        public Inner(int a)
        {
            this.a = a;
        }
        public void print()
        {
            System.out.println("Inner a =" + this.a);
            System.out.println("Outer a = " + Test1.this.a);
        }
    }
    public static void main(String[] args)
    {
        Outer.Inner i= new Outer(2).new Inner(3);
        i.print();
    }
}
打印结果是:3    2
******************************************************静态内部类******************************************************************
(1)静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例

public class Outer {
    public int a;
    public Outer(int a)
    {
        this.a = a;
    }
    public static class Inner{
        public int b;
        public Inner(int b)
        {
            this.b = b;
        }
    }
    public static void main(String[] args)
    {
        Inner b = new Inner(1);
        Outer.Inner o = new Inner(1);
        Outer.Inner o = new Outer(1).new Inner(1);  //不合法

    }
}
(2)静态内部类可以直接访问外部类的静态变量,如果访问外部类的实例成员,必须通过外部类的实例访问
public class Outer{
    private int a;
    private static int b;
    public static class Inner{
        public static int num;
        public int c = a; //不合法
        public int d = b; //可以
        public int e = new Outer().a;    
    }
}
(3)在静态内部类中可以定义静态成员和实例成员
(4)可以通过完整的类名直接访问静态内部类的静态成员上面的number可以用 Outer.Inner.number访问

                            局部内部类
局部内部类是在一个方法中定义的内部类,它的可见范围是当前方法,和局部变量一样,局部内部类不能用访问控制修饰符修饰以及static修饰
(1)只能在当前方法使用
(2)不能包含静态成员
(3)局部内部类的内部类也不能用访问控制修饰符修饰以及static修饰
(4)局部内部类和实例内部类一样,可以访问外部类的所有成员,此外,局部内部类还可以访问所在方法中的final类型的参数和变量
public class A {
    private int a;
    public A(int a)
    {
        this.a = a;
    }
    public void method()
    {
        a = 10;
        final int NUMBER = 50;
        class B{
            public int b = a;
            public int c = NUMBER;
            
        }
    }
}
                                                         匿名类
匿名类是一种特殊的内部类,这种类没有名字
package test;

public class NoNameClass {
    private int number;
    public NoNameClass()
    {
        System.out.println("default constructor");
    }
    public NoNameClass(int number)
    {
        System.out.println("Another constructor");
    }
    public void method()
    {
        System.out.println("from NoNameClass");
    }
    public static void main(String[] args)
    {
        new NoNameClass().method();
        NoNameClass n = new NoNameClass() {
            public void method() {
                System.out.println("from anyone");
            }
        };
        n.method();
    }
}
打印的结果是:
default constructor
from NoNameClass
default constructor
from anyone
package test;

public class NoNameClass {
    private int number;
    public NoNameClass()
    {
        System.out.println("default constructor");
    }
    public NoNameClass(int number)
    {
        System.out.println("Another constructor");
    }
    public void method()
    {
        System.out.println("from NoNameClass");
    }
    public static void main(String[] args)
    {
        new NoNameClass().method();
        NoNameClass n = new NoNameClass() {
            
        };
        n.method();
    }
}
打印结果是:
default constructor
from NoNameClass
default constructor
from NoNameClass
匿名类的类体重写了method方法,而且不能缩小权限,类似于继承
(1)匿名类本身没有构造方法,但是会调用父类的构造方法
(2)匿名类尽管没有构造方法,但是可以在匿名类中提供一段实例初始化代码,Java虚拟机会在调用了父类的构造方法后,执行这段代码
package test;

public class NoNameClass {
    private int number;
    public NoNameClass()
    {
        System.out.println("default constructor");
    }
    public NoNameClass(int number)
    {
        System.out.println("Another constructor");
    }
    public void method()
    {
        System.out.println("from NoNameClass");
    }
    public static void main(String[] args)
    {
        new NoNameClass().method();
        int num = 1;
        NoNameClass n = new NoNameClass(num) {
            {
                System.out.println("hello");
            }
            public void method()
            {
                System.out.println(num);
            }
            {
                System.out.println("hello");
            }
        };
        n.method();
    }
}
打印结果是:
default constructor
from NoNameClass
Another constructor
hello
hello
1
注意此处在调用完父类的构造方法后会执行完全部的初始化代码
原创粉丝点击