搞懂 JAVA 内部类

搞懂 JAVA 内部类

前些天写了一篇关于 2018 年奋斗计划的文章,其实做 Android 开发也有一段时间了,文章中所写的内容,也都是在日常开发中遇到各种问题后总结下来需要巩固的基础或者进阶知识。那么本文就从内部类开刀。

本文将会从以下几部分来总结:

  1. 为什么要存在内部类
  2. 内部类与外部类的关系
  3. 内部的分类及几种分类的详细使用注意事项
  4. 实际开发中会遇到内部类的问题

内部类为什么存在

内部类 ( inner class ) : 定义在另一个类中的类

我们为什么需要内部类?或者说内部类为啥要存在?其主要原因有如下几点:

  • 内部类方法可以访问该类定义所在作用域中的数据,包括被 private 修饰的私有数据
  • 内部类可以对同一包中的其他类隐藏起来
  • 内部类可以实现 java 单继承的缺陷
  • 当我们想要定义一个回调函数却不想写大量代码的时候我们可以选择使用匿名内部类来实现

内部类方法可以访问该类定义所在作用域中的数据

做 Android 的我们有时候会将各种 Adapter 直接写在 Activity 中,如:

class MainActivity extends AppCompatActivity{
    ....
    private List<Fragment> fragments = new ArrayList();
    
    private class BottomPagerAdapter extends FragmentPagerAdapter{
        ....
        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }
        ...
    }
    ...
}
复制代码

上文中 BottomPagerAdapter 便是 MainActivity 的一个内部类。也可以看出 BottomPagerAdapter 可以直接访问 MainActivity 中定义的 fragments 私有变量。如果将 BottomPagerAdapter 不定义为内部类访问 fragments 私有变量 没有 getXXX 方法是做不到的。 这就是内部类的第一点好处。

可是为什么内部类就可以随意访问外部类的成员呢?是如何做到的呢?

当外部类的对象创建了一个内部类的对象时,内部类对象必定会秘密捕获一个指向外部类对象的引用,然后访问外部类的成员时,就是用那个引用来选择外围类的成员的。当然这些编辑器已经帮我们处理了。

另外注意内部类只是一种编译器现象,与虚拟机无关。编译器会将内部类编译成 外部类名$内部类名 的常规文件,虚拟机对此一无所知。

内部类可以对同一包中的其他类隐藏起来

关于内部类的第二个好处其实很显而易见,我们都知道外部类即普通的类不能使用 private protected 访问权限符来修饰的,而内部类则可以使用 private 和 protected 来修饰。当我们使用 private 来修饰内部类的时候这个类就对外隐藏了。这看起来没什么作用,但是当内部类实现某个接口的时候,在进行向上转型,对外部来说,就完全隐藏了接口的实现了。 如:

public interface Incrementable{
  void increment();
}
//具体类
public class Example {

    private class InsideClass implements InterfaceTest{
         public void test(){
             System.out.println("这是一个测试");
         }
    }
    public InterfaceTest getIn(){
        return new InsideClass();
    }
}

public class TestExample {

 public static void main(String args[]){
    Example a=new Example();
    InterfaceTest a1=a.getIn();
    a1.test();
 }
}
复制代码

从这段代码里面我只知道Example的getIn()方法能返回一个InterfaceTest实例但我并不知道这个实例是这么实现的。而且由于InsideClass是private的,所以我们如果不看代码的话根本看不到这个具体类的名字,所以说它可以很好的实现隐藏。

内部类可以实现 java 单继承的缺陷

我们知道 java 是不允许使用 extends 去继承多个类的。内部类的引入可以很好的解决这个事情。 以下引用 《Thinking In Java》中的一段话:

每个内部类都可以队里的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类没有影响 如果没有内部类提供的、可以继承多个具体的或抽象的类的能力,一些设计与编程问题就难以解决。 接口解决了部分问题,一个类可以实现多个接口,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值