打好Java基础,从使用内部类开始!

简介: 本文主要介绍 Java中内部类的用法

今天又周五了呀,正在想明天周六有啥安排的时候,一声惊讶声打断了我


小蔡小菜,你看看这组代码,好灵活啊


听到领桌小王的惊讶,我扭头看了下他的屏幕,这不就是内部类么。用的好当然就灵活啦,只是我们平常没怎么用。


内部类用的好真的好灵活呀,我对这一块还不是很熟悉,看来还得多学习学习!小菜,看你的样子好像挺了解的,你能给我讲讲吗?


看着小王如饥似渴的眼色,我不由有点心虚,内心活动也是极其复杂:我平时也没咋用,只是有个大概的了解,讲出来不就献丑了,连忙声道:


好说好说,不过今天都周五了,也不差这一时半会,咱们还是想想明天有啥活动,等下周来我再给你好好讲讲!


小王仿佛被我忽悠过去了,也没看到我眼神中的慌乱,答应了下来。


好在有惊无险,周末还能有啥安排,赶紧把内部类安排上!


初识


比起面向对象编程中其他的概念来,接口和内部类更深奥复杂,比如 C++ 就没有这些。将两者结合起来,可以解决 C++ 中用多重继承所能解决的问题,然后,多重继承在 C++ 中被证明是相当难以使用的,相比较而言,Java 的接口和内部类就容易理解多了!


一、内部类如何创建


内部类,顾名思义就是类中类,将类定义在外围类里面:


网络异常,图片无法展示
|


因为MonkeyPig两个类是定义在 Animal 类中,因此使用起这两个内部类跟使用普通类没什么区别。下面这组代码相信小伙伴也不陌生:


网络异常,图片无法展示
|


通过定义方法,来返回执行内部类的引用。不知道细心的小伙伴有没有注意到内部类的引用有点奇怪:Animal.Monkey。这也是内部类的区别之一,如果要在外部类的非静态方法之外获取某个内部类的对象,需要具体指明这个对象的类型

OuterClassName.InnerClassName


二、内外相连


内部类存在于外部类里层,因此也具有一定特权:内部类可以访问外围对象的所有成员,不需要任何特殊条件,此外,内部类还拥有外部类的所有元素的访问权。


网络异常,图片无法展示
|


上组代码中我们可以看到,InnerArray可以访问到OuterArray中的每一个属性,就像自己拥有它们一样,这带来了很大的方便。


三、new 和 this


这两个关键字我们肯定都不陌生了,我们平时用到最多的肯定就是new一个对象出来。


public class OuterClass {
    class InnerClass {
    }
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
    }
}


当我们需要OuterClass对象的时候,我们顺手就来了个new OuterClass(),但是如果我们需要的是InnerClass对象,那么又该如何处理呢?答案便是:


InnerClass inner = outer.new InnerClass();


可能觉得有点奇怪,为什么此处的new需要以OuterClass对象引用,这是因为内部类对象会暗暗地连接到创建它的外部类对象上,因此必须使用外部类的对象来创建内部类对象。如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。


this关键字是用来生成对外部类对象的引用,这样产生的引用自动具有正确的类型:


网络异常,图片无法展示
|


四、局部内部类


我们上面看到的内部类都是定义在外部类中,这也是内部类的典型用处。但是,我们也可以在一个方法里面或者任意的作用域里面定义内部类。这种也被称为局部内部类


网络异常,图片无法展示
|


Pig类是getPig()方法的一部分,而不是OuterClass的一部分,所以在getPig()

之外不能访问Pig类。


五、匿名内部类


在了解什么是匿名内部类之前,我们先看一组代码:


网络异常,图片无法展示
|


animal()这个方法将返回值的生成与表示这个返回值的类定义结合在一起。而且这个类是匿名的,它没有名字,正常形式应该是这样的:


网络异常,图片无法展示
|


匿名类再访工厂:


网络异常,图片无法展示
|


通过内部类获取外部类的实现,这样子Implementation1的构造器都可以是private的,并且没有任何必要去创建作为工厂的具体类,这样所产生的语法也更具有实际意义,也可以运用在单例模式中。


六、嵌套类


如果不需要内部类对象与外围类之间有联系,就可以将内部类声明为static,这通常称为嵌套类。普通的内部类对象隐式地保存了一个引用,指向创建它的外围类对象,然而,当内部类是static的时候,就意味着:


  • 要创建嵌套类的对象,并不需要其外围类的对象


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


网络异常,图片无法展示
|


main()方法中没有任何NestClass对象是必须的,而是使用选取static成员的普通语法来调用方法。


接口内部类


正常情况下,不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分。你放到接口中的任何类都自动是publicstatic的。因为类是static的,只是将嵌套类置于接口的命名空间内,这并不违反接口的规则。你甚至可以在内部类中实现其外部类的接口:


网络异常,图片无法展示
|


如果你想要的创建某些公共代码,使得它们可以被某个接口的所有不同实现所共用,那么使用接口内部的嵌套类会显得很方便,尽管在 Java 8 之后可以使用 default 来默认实现接口方法。


七、继承内部类


内部类作为一种类,被继承当然也是被允许的。但是因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候,那个指向外围类对象的引用必须被初始化,而在导出类中不再存在可连接的默认对象:


网络异常,图片无法展示
|


可以看到,通过这样继承是会报错的,解决方法便是:


class ExtendClass {
    class Inner{}
}
class WithInner extends ExtendClass.Inner {
    public WithInner(ExtendClass extendClass) {
        extendClass.super();
    }
}


因此我们需要记住,如果要继承一个内部类的时候,必须在构造器内使用外部类.super(),这样才能提供了必要的引用,然后程序才能编译通过。


八、覆盖内部类?


当子类继承父类时,子类可以覆盖父类的方法。那么问题来了,内部类能否被覆盖?我们通过看一组代码来找找答案:


网络异常,图片无法展示
|


从这个例子中我们可以看到,当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化,这两个内部类是完全独立的两个实体,各自在自己的命名空间内。


九、为什么要使用内部类?


我们在回答这个问题之前先明白一件事情:


每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响


这句话很清楚的说明了内部类的能力,如果没有内部类提供的、可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决,从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,为内部类有效地实现了"多重继承"




目录
相关文章
|
10天前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
41 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
4月前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
152 2
|
1月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
17天前
|
Java 编译器
【Java】内部类
【Java】内部类
17 0
|
2月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
2月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
33 5
|
3月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
36 6
|
2月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
4月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
79 2
|
4月前
|
安全 Java