内部类详解

内部类

概念

在类内部可定义成员变量和方法,且在类内部也可以定义另一个类。如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类(或称为嵌套类),而类 Outer 则称为外部类(或称为宿主类)。

内部类可以很好地实现隐藏,一般的非内部类是不允许有 private 与 protected 权限的,但内部类可以。(非静态)内部类拥有外部类的所有元素的访问权限。

分类

内部类可以分为:实例内部类、静态内部类和局部内部类,关系为:一般把实例内部类就叫成成员内部类

内部类与外部类的关系

成员内部类的创建需要依赖于外部类对象-(成员方法必须通过对象调用),在没有外部类实例之前无法创建成员内部类对象

内部类与外部类相对独立,不是is a 的关系(发动机-汽车)

私有属性的互相访问,实例内部类可以直接访问外部类(所有元素),而静态内部类不能访问外部类的非静态元素,而外部类访问内部类需要内部类的对象来访问

public class Outer {
    private String name = "CK";
    class Inner {
        private String name1 = "Ql";
        public void innerTest() {
            System.out.println(name);---->Ck
        }
    }
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        String name = inner.name1;---->Ql
    }
}

在内部类内部使用隐藏(private)的外部类对象(隐藏的this)

public class Outer {
    private String name = "CK";
    class Inner {
        private String name = "Ql";
        public void innerTest() {
            //如果不定义Ql,name=Ck;定义了Ql,name=Ql。
            //System.out.println(name);
            System.out.println(this.name);---->Ql
            System.out.println(Outer.this.name);---->Ck
        }
    }

特点

内部类的特点如下:

  1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
  2. 内部类不能用普通的方式访问,外部类访问内部类需要内部类的对象来访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
  3. 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。

访问修饰符

对于外部类来说,只有两种修饰,public和默认(default),因为外部类放在包中,只有两种可能,包可见和包不可见。

从作用范围的角度来说,对于顶级类(外部类)来说,有两种修饰符:public和默认(default)。因为外部类的上一单元是包,所以外部类只有两个作用域:同包,任何位置。因此,只需要两种控制权限:包控制权限和公开访问权限,也就对应两种控制修饰符:默认(default)和public。

对于内部类来说,可以有所有的修饰,因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能。

实例内部类

成员内部类(上图的实例内部类):类比成员方法(其实指的就是实例方法),不能拥有静态域但是可以访问外部类的静态域

public class Outer {
    private String name = "CK";
    private static int a = 6;
    class Inner {
        //static String name = "Ql";//不能定义静态变量和方法
        public void innerTest() {
            System.out.println(name);//访问非静态成员
            System.out.println(a);//访问静态成员
        }
    }
}

创建成员内部类对象

外部类内部,外部类外部

Outer.Inner inner = new Outer().new Inner();

静态内部类

定义在外部类的内部,使用static修饰,类比静态方法,静态内部类不需要外部类对象产生就能使用,不能访问外部类的成员域,但能访问静态域

public class Outer {
    private String name = "CK";
    private static int a = 6;
    static class Inner {
        private String name1 = "Ql";
        public void innerTest() {
            System.out.println(name);//这里会报错
            System.out.println(a);
        }
    }
}

创建静态内部类对象

外部类内部

Inner inner1 = new Inner();

外部类外部

Outer.Inner inner = new Outer().new Inner();

普通内部类只能包含非静态变量非静态方法非嵌套类

静态内部类可以包含静态和非静态变量静态和非静态方法静态和普通内部类

静态内部类可以定义在接口中,并作为接口的一部分来使用。

局部内部类

方法或某个作用域内的内部类,称为局部内部类。匿名内部类就是一种局部内部类。

public class Outer {
    private String name = "CK";
    private static int a = 6;
    public void InnerClass() {
        //解掉这行注释name就会报错,可以访问外围类的成员变量。如果是static方法,则只能访问static修饰的成员变量。
    //public static void InnerClass() {
        class Inner {
            private double a  = Math.random();
            public void innerTest() {
                System.out.println(a);
                System.out.println(name);
            }
        }
        Inner inner = new Inner();
        inner.innerTest();
    }
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.InnerClass() ;
    }
}

只能在方法内部,类(局部内部类)定义之后使用,不存在外部可见性问题,因此没有访问修饰符。

不能在局部内部类中使用可变的局部变量。

可以访问外围类的成员变量。如果是static方法,则只能访问static修饰的成员变量。

可以使用final 或 abstract修饰。

匿名内部类

由于匿名内部类不利于代码的重用,因此,一般在确定此内部类只会使用一次时,才会使用匿名内部类。

必须继承一个抽象类或者实现一个接口

没有构造方法

public class Outer {
    public Runnable test(){
        //匿名内部类
        return new Runnable() {
            @Override
            public void run() {
                System.out.println("Ck");
            }
        };
    }
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test().run();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值