java内部类

系列文章目录

第一章 万事万物皆对象
第二章 java构造器
第三章 java访问权限
第四章 java初始化
第五章 java继承
第六章 java重载与重写
第七章 java接口和抽象类
第八章 java数组
第九章 java内部类
第十章 java时间操作
第十一章 final关键字
第十二章 java字符串
第十三章 java异常
第十四章 java泛型
第十五章 java IO操作
第十六章 java NIO操作
第十七章 java zip压缩
第十八章 java反射
第十九章 java反射之Type接口
第二十章 java8流式操作
第二十一章 java8函数式编程



原文链接 https://zhhll.icu/2020/java基础/面向对象/9.java基础之内部类/

内部类

内部类是一种较为特殊的类形式,定义在另一个类中的类,叫做内部类,是主类的一部分,可以把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性。

作用

  • 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据
  • 内部类可以对同一个包中的其他类隐藏起来

内部类分为

  • 静态内部类
  • 成员内部类
  • 局部内部类
  • 匿名内部类

成员内部类

成员内部类可以等同的看做是成员变量,可以有权限修饰符,内部不能有静态声明

public class Outter {

    class Inner {
        public void print(String s) {
            System.out.println(s);
        }
    }

    public Inner buildInner() {
        return new Inner();
    }

    public static void main(String[] args) {
        Outter outter = new Outter();
        Inner inner = outter.buildInner();
        inner.print("输出");
    }
}
成员内部类与外部类联系

成员内部类可以使用外部类的所有成员,而且不需要任何特殊条件,且拥有其对于外部类所有元素的访问权。

在创建成员内部类对象时,它会与创建它的外围对象有某种联系隐式引用(内部类对象会秘密的捕获一个指向外部类的引用,通过这个引用可以用来访问外部类的成员),通过这个隐式引用可以访问外部类的所有成员

public class Sequence {

    private Object[] items;

    private int next;

    public Sequence(int size) {
        items = new Object[size];
    }

    /**
     * 添加元素
     *
     * @param obj
     */
    public void add(Object obj) {
        if (next < items.length) {
            items[next] = obj;
            next++;
        }
    }

    public SequenceSelector selector() {
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Sequence sequence = new Sequence(10);
        for (int i = 0; i < 10; i++) {
            sequence.add(i);
        }
        SequenceSelector selector = sequence.selector();
        while (!selector.end()) {

            System.out.print(selector.current() + " ");
            selector.next();
        }
    }

    private class SequenceSelector {

        private int current = 0;

        public boolean end() {
            return current == size();
        }

        public int size() {
            return items.length;
        }

        public Object current() {
            return items[current];
        }

        public void previous() {
            if (current > 0) {
                current--;
            }
        }

        public void next() {
            if (current < items.length) {
                current++;
            }
        }
    }
}

使用.this和.new

在成员内部类如何生成外部类对象的引用,使用外部类名.this

public class DoThis {
    class Inner{
        public DoThis outer(){
            return DoThis.this;
        }
    }

    public void f(){
        System.out.println("DoThis.f()");
    }

    public Inner inner(){
        return new Inner();
    }

    public static void main(String[] args) {
        DoThis doThis = new DoThis();
        Inner inner = doThis.inner();
        inner.outer().f();
    }
}

外部类如何创建成员内部类的对象,需要使用外部类实例.new

public class DoNew {

    class Inner {
        public void f(){
            System.out.println("Inner.f()");
        }
    }

    public static void main(String[] args) {
        DoNew doNew = new DoNew();
        Inner inner = doNew.new Inner();
        inner.f();
    }
}

在拥有外部类对象之前是不可能创建成员内部类对象的,成员内部类对象会连接到创建它的外部类对象上,静态内部类不需要外部类对象的引用。

对于私有的成员内部类,外部类是可以访问到它的,其他的类无法访问到,如下

public class DoNew {

    private class Inner {
        public void f(){
            System.out.println("Inner.f()");
        }
    }

    public static void main(String[] args) {
        DoNew doNew = new DoNew();
        // 外部类中可以访问到
        Inner inner = doNew.new Inner();
        inner.f();
    }
}

public class Test {
    public static void main(String[] args) {
        DoNew doNew = new DoNew();
        // 其他类无法访问
        // 'DoNew.Inner' has private access in 'DoNew'
        //doNew.new Inner();
    }
}

局部内部类

在方法作用域内创建的类,称为局部内部类,局部内部类没有访问修饰符,可以等同的看做是局部变量,局部内部类在访问局部变量时,局部变量必须使用final修饰

Variable 'name' is accessed from within inner class, needs to be final or effectively final
public class MethodOuter {

    public Destination desc(String s){
        // 局部内部类
        class Inner implements Destination{
            @Override
            public void f(){
                System.out.println("Inner.f()传入参数"+s);
            }
        }
        return new Inner();
    }

    public static void main(String[] args) {
        MethodOuter methodOuter = new MethodOuter();
        methodOuter.desc("test").f();
    }
}

Inner是desc()方法的一部分,在方法之外访问不到

匿名内部类

匿名内部类,就是没有定义类名的一种嵌套类
如一个接口/类的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余

public interface Contents {
    void f();
}

public class Outer1 {
    public Contents contents(){
        return new Contents(){
            @Override
            public void f() {
                System.out.println("Contents匿名内部类.f()");
            }
        };
    }

    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        outer1.contents().f();
    }
}

静态内部类

静态内部类可以等同的看做是静态变量,可以有权限修饰符

静态内部类,内部类对象与外部类对象之间没有联系,将内部类声明为static,普通的内部类对象隐式的保存了一个引用,指向创建它的外部类对象,当内部类是static的时候,意味着

  • 要创建静态内部类的对象,并不需要其外部类的对象

  • 不能从静态内部类的对象中访问非静态的外围对象

    普通内部类不能有static数据和static字段,也不能包含静态内部类,但是静态内部类可以。

    public class Outer2 {
        private static class Inner2{
            private static int i = 0;
            private static void f(){
                System.out.println("Inner2.f()");
            }
        }
    
        public static void main(String[] args) {
            Inner2.f();
        }
    }
    

在创建静态内部类时不需要将静态内部类的实例绑定在外部类实例上。

接口内部类

静态内部类可以作为接口的一部分,放到接口中任何类都是public static的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾光师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值