前言
之前我们对Java的抽象类与接口进行了一定的了解练习,今天结合类和对象的知识我们来学习内部类。本篇文章将详细介绍Java语言中内部类的实例化内部类,局部内部类,匿名内部类和静态内部类定义及其性质,让我们开始吧!!
1.内部类的概念
当一个事物的内部,有部分还需要一个完整的结构来描述,而这个内部的结构又只为外部结构所运用,此时这个内部的完整结构最好使用内部类。在Java中,类可以在类中定义,也可以在方法中定义,前者称为内部类,后者称为外部类。 内部类也是封装的一种体现。
public class OuterClass{ ⬅外部类
class InnerClass{ ⬅内部类
}
}
🚨注意事项!!!🚨
-
- 定义在class花括号{}外部的类,即使是在一个文件里,也不算是内部类。
-
- 内部类和外部类共用同一个Java类源文件,但是编译之后会形成单独的字节码文件
代码如下:
编译前
编译后
2.内部类的种类
根据在外部类内部定义位置不同与修饰符不同可以大致分为以下几类:
- 成员内部类:普通内部类(没有任何修饰),静态内部类(static修饰)
- 局部内部类(在外部类成员方法中定义)、匿名内部类
🚨可公开的情报!!!🚨
内部类在我们日常使用中并不是非常常用,我们有时在看一些库的代码时可能会遇到,日常开始使用的最多的是匿名内部类。
2.1静态内部类
【定义】:被static修饰的内部类叫静态内部类
【性质】:
- 在静态内部类中只能访问外部类的静态成员
如果想要在内部类中访问,需要在内部类中实例化一个外部类对象,之后可以通过引用实现变量访问。
- 创建内部类对象时,不需要先创建外部类对象
- 在外部类方法外实例化内部类时类的形式为
外部类.内部类 类名 = new 外部类.内部类();
- 在外部类中实例化内部类对象时不需要加
外部类.
前缀来实例化
【样例代码】:
package demo2;
class OuterClass{
int a = 100;
static int b = 100;
public void methodA(){}
public static void methodB(){}
//被static修饰的内部类,静态内部类
public static class InnerClass{
public void methodInner(){
a = 10;//编译失败,因为a不是静态外部类成员变量
b = 20;
methodA();//编译失败,因为该方法不是静态外部类成员方法
methodB();
}
}
}
public class test2 {
public static void main(String[] args) {
//静态内部类对象创建和访问
OuterClass. InnerClass t2 = new OuterClass.InnerClass();
t2.methodInner();
}
}
2.2实例化内部类
定义:不带static的普通内部类
性质:
- 外部类的任何成员都能在内部类的成员方法中直接访问
- 外部类不能直接访问内部类成员,要先对内部类进行实例化
- 创建实例内部类对象时前提要先对外部类进行实例化创建
- 在实例内部类方法中访问同名成员时,优先访问自己的,没有则访问外部类中成员(如想访问外部类成员需在对应对象前加
外部类类名.this.同名成员
) - 因该内部类和外部类处同一位置,其也受public、private限制
public class OutClass {
private int a;
static int b;
int c;
public void methodA(){
a = 10;
System.out.println(a);
}
public static void methodB(){
System.out.println(b);
}
// 实例内部类:未被static修饰
class InnerClass{
int c;
public void methodInner(){
// 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
a = 100;
b =200;
methodA();
methodB();
// 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
c = 300;
System.out.println(c);
// 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
OutClass.this.c = 400;
System.out.println(OutClass.this.c);
}
}
public static void main(String[] args) {
// 外部类:对象创建 以及 成员访问
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(OutClass.b);
System.out.println(outClass.c);
outClass.methodA();
outClass.methodB();
System.out.println("=============实例内部类的访问=============");
// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
// 创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.methodInner();
}
2.3匿名内部类
定义:没有显式定义类名,而是在创建对象时通过传递实现了某个接口或继承了某个类的代码块的类。(有时使用匿名内部类可以无需创建新的类,减少代码长度)
在实际开发中,实现一个类或接口的方法在程序中也许只会使用一次,为了这一次的使用在特地去创建一个实现的类,太过麻烦,此时我们就可以匿名内部类。
interface Interface01{
void method();
}
class Hello implements Interface01{//专门创建的类
@Override
public void method(){
System.out.println("Hello!");
}
}
使用匿名内部类:
public class niming {
public static void main(String[] args) {
Interface01 interface01 = new Interface01() {//这就是匿名内部类
@Override
public void method() {
System.out.println("niming::Hello!");
}
};
interface01.method();
}
}
框选部分即为匿名内部类
上面匿名内部类还有一种实现格式:
public static void main(String[] args) {
new Interface01() {//这就是匿名内部类
@Override
public void method() {
System.out.println("niming::Hello!");
}
}.method();//直接进行调用
}
能实现同样的效果~
2.4局部内部类
定义:定义在外部类成员方法里的内部类,该种内部类只能在其定义的位置中使用。
PS:一般用的非常少,简单了解格式即可🫸🫸
【性质】:
- 局部内部类只能在所定义的方法内部使用
- 不能被public、static等修饰符修饰
- 编译器对其也有自己的的字节码文件
命名格式:外部类名字$ 数字 内部类名字.class
结语
好了以上就是本篇“【Java】类之内部类”博客的全部内容啦,感谢各位的阅读=v=,如有不足之处欢迎在评论区指正哦!!
觉得有帮助的话别忘了点赞三连支持一下欧!拜托啦这对我真的很重要o(>ω< )o!!!