Java内部类

何为内部类

java中,把一个类定义在另一个类的里面,或者方法里面,这样的类称为内部类。内部类可以随意访问外部类的任何成员,但是相反,外部类却不可随意访问内部类的成员,需要先实例化内部类方可调用。

内部类的分类

1.成员内部类
2.局部内部类
3.匿名内部类
4.静态内部类

成员内部类

成员内部类定义与一个类的里面,大概样子如下所示

public class Outer {
    public String outer ="outer";
    //定以外部类方法
    public void isOuter(){
        System.out.println(outer);
    }
    //定义内部类
    class Inner{
        public String inner ="inner";
        public void isInner(){
            System.out.println(inner);
        }
    }
}

可以看到内部类Class Inner定义在外部类Class Outer的里面,为了证实刚才的结论,我作出了一些调用
在这里插入图片描述
可以清楚看到,内部类可以直接调用外部类的任何成员(包括private修饰);而外部类要访问内部成员的话就必须要先实例化;
在这里插入图片描述
如图实例化后,外部类就可以正常调用内部类的成员(测试的时候注意注释掉一些互相调用的代码,以免造成死循环)
除了通过上面的那种通过return new Inner()完成实例化,还有一种方式

  Outer out = new Outer();
  Inner in = out.new Inner();
  //或者这样
  Outer.Inner in2 = out.new Inner();

而内部成员类可以使用任何的修饰符,如同private
所以两种实例化该怎么使用要看个人的需求了
在这里插入图片描述

局部内部类

局部内部类就是一个定义在一个方法里,或者定于在一个作用域了,跟普通类的局部变量非常类似,通过的,局部内部类一样不能有访问修饰符,它大体的样子大概是这样的:

public class OuterMethod {
    public String outer ="outer";
    private String outerPr = "outerPr";
    //这是外部类的方法
    public void whatInner(){
        String outMethodMember = "局部变量";
        //定以局部内部类
        class MethodInner{
            //定以局部内部类的方法
            public void isInner(){
                System.out.println("Inner");
            }
            
        }
    }
}

在这里插入图片描述
访问修饰符都不能有,以及内部类的成员不能有static,但是他们可以拥有访问修饰符和final
在这里插入图片描述
这里的原因我估摸着虚拟机加载时,会把static修饰的成员都先加载了,就像平时可以直接调用static方法和变量一样,而局部内部类,是需要在外部类实例化后,再对内部类实例化,里面的成员才会开始加载,与当初定以static的目的不一致,具体的我也不是特别清楚为什么了…

匿名内部类

匿名内部类和局部内部类很相似,不过匿名内部类的写法更为简便,省去了起类名的过程。不过匿名内部类的使用有一个前提:要继承父类或者实现接口

匿名内部类极大的方便了我们的编写,例如我们的Thread

public class Threads extends Thread{
    //正常创建类
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(this.getName());
        }
    }

    public static void main(String[] args) {
        Threads t1 = new Threads();
        Threads t2 = new Threads();
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();
    }
    //匿名内部类创建
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("t1");
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("t2");
                }
            }
        }.start();
    }
}

因为代码简单的原因,差距并没有体现出来,但是可以看到,普通创建的话需要起一个类似于 t1 , t2 等这类名字,匿名内部类就可以省去了。可能因为这样,在JDK1.8之后推出了Lambda表达式,真的是把java代码简洁到了极致的一个程度,大家可以去了解下这个Lambda

静态内部类

静态内部类,顾名思义就是在内部类上加了static关键词修饰。一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类。静态内部类是不需要依赖于外部类的,并且它不能使用非static成员变量或者方法,不管外部还是内部

public class OuterStatic {
    public String outer ="outer";
    public static String outerstaic = "out";
    private String outerPr = "outerPr";

    private static class Inner{
        public static  String inner ="inner";
        private String innerPr = "innerPr";
        public static  void isInner(){
            System.out.println(inner);
            //无法使用
            System.out.println(innerPr);
            System.out.println(outerPr);
        }
    }
    public static void main(String[] args) {

        Inner inner = new Inner();

        //out.isOuter();
        inner.isInner();

    }
}

可以看到,可以直接不通过外部类,直接实例化一个静态内部类,或者我们可以按照调用外部类的静态成员一样,直接调用

        OuterStatic.Inner.isInner();

内部类是JAVA很重要的一个环节:
(1)极大的增强了java代码的灵活性,
(2)它可以有效地对外界隐藏起来自己
(3)可以解决java单继承的缺点,即使外部类继承了其他父类,也不会影响内部类的继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值