当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
基本语法格式
class A{
class B{ //B就是A的内部类
//……
}
}
复制代码
内部类的分类
1、实例内部类
2、静态内部类
3、本地内部类(不是很常用)
4、匿名内部类(这里简单了解)
内部类一定要知道是什么类型的内部类,要加以区别
实例内部类
class A{
int age;
String name;
class B{ //B就A的内部类
int score;
public static int sex;//err,实例内部类里面了不能定义静态的成员变量,静态的要先被加载,但是类又需要对象才能加载,所以在内部类里面不能定义静态的成员变量或者方法
public void func() {
System.out.println("实例内部类的普通成员方法");
}
public static void func2() {
System.out.println("实例内部类的静态成员方法"); //err,实例内部类里面不能定义静态地成员方法
}
}
}
复制代码
小总结:实例内部类里面不能定义静态的
如何进行实例内部类的实例化?
class A{
int age;
String name;
class B{ //B就A的内部类
int score;
public void func() {
System.out.println("实例内部类的普通成员方法");
}
}
}
public class Test {
public static void main(String[] args) {
A a = new A();//先进行实例化外部类
//A.B b = a.new B();
//外部类的类名.内部类的类名 对象名 =外部类的对象名.new 内部类名();
//另一种不创建外部类对象的方法:
A.B b = new A().new B();
}
}
复制代码
实例内部类如何进行访问?
class A{
int age=78;
int data1=12;
static int data2;
public void test() {
System.out.println("haha");
}
class B{ //B就A的内部类
int data3=78;
public void func() {
System.out.println("实例内部类的普通成员方法");
}
public B(){
System.out.println("实例内部类的构造方法");
}
public void func2() {
System.out.println(data3);
System.out.println(data1);//内部类也是可以访问外部类的成员变量的
System.out.println(age);
System.out.println(data2);
}
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
A.B b = a.new B();
// A.B b = new A().new B();
b.func();
b.func2();
}
}
//打印的结果:
//实例内部类的构造方法
//实例内部类的普通成员方法
//78
//12
//78
//0
复制代码
如何打印外部类的同名成员变量?
要是在实例内部类和实例外部类里面都有同一个成员变量,会打印出哪一个呢?
class A{
int age=78;
int data1=12;
static int data2;
int data3=1;
public void test() {
System.out.println("haha");
}
class B{ //B就A的内部类
int data3=78;
public void func() {
System.out.println("实例内部类的普通成员方法");
}
public B(){
System.out.println("实例内部类的构造方法");
}
public void func2() {
System.out.println(data3);//data在内部类和外部类都有定义
System.out.println(data1);//内部类也是可以访问外部类的成员变量的
}
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
A.B b = a.new B();
// A.B b = new A().new B();
b.func();
b.func2();
}
}
//打印的结果是内部类的data3
复制代码
要想打印出实例外部类的data3,就要专门指明外部类
public void func2() {
System.out.println(this.data3);//内部类的data3
System.out.println(A.this.data3);//外部类的data3,
}
//注意:由于func2是在内部类里面的,所以第一个data3的this是可以省略的,但是第二个data3的this不能省略,指定是外部类的data3
复制代码
小总结:在实例内部类中访问同名的成员变量时,优先访问自己内部类的,如果要访问外部类的同名成员变量,一定要使用外部类名.this.成员名
-一个java文件却生成了3个字节码文件,说明有几个类就会有生成几个字节码文件
image-20220514090532849
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oeI4NWAH-1652496918057)(dengchuanfei-typora.oss-cn-hangzhou.aliyuncs.com/image-20220…)]
并且实例内部类的字节码文件的命名方法是外部类$内部类.class
静态内部类
静态内部类里面没有那么多的限制,可以定义实例成员变量、实例方法和静态成员变量和静态方法
class Outerclass{
public int data1=1;
private int data2=2;
public static int data3=3;
public Outerclass(){
System.out.println("Outerclass的构造方法");
}
public void func() {
System.out.println("Outerclass的func方法");
}
static class Innerclass { //静态内部类
public int data4=4;
public static int data5=5;//静态内部类里面可以就可以定义静态的成员变量
public Innerclass() {
System.out.println("Innerclass的构造方法");
}
public void func2() {
System.out.println(data3);
//不能在静态内部类里面直接访问外部类的非静态成员变量,所以上面的data1和data2就在func2中不能访问
}
}
}
public class Test {
public static void main(String[] args) {
//Outerclass outerclass = new Outerclass();
Outerclass.Innerclass innerclass = new Outerclass.Innerclass();//静态内部类的实例化,静态的不依赖对象,所以不需要将外部类进行实例化,直接创建静态内部类对象就行了
innerclass.func2();
}
}
复制代码
要是想要调用外部类的非静态成员变量,可以传一个外部类对象
class Outerclass{
public int data1=1;
private int data2=2;
public static int data3=3;
public Outerclass(){
System.out.println("Outerclass的构造方法");
}
public void func() {
System.out.println("Outerclass的func方法");
}
static class Innerclass {
public int data4=4;
public static int data5=5;//静态内部类里面可以就可以定义静态的成员变量
public Outerclass outerclass;//创建外部类对象
public Innerclass(Outerclass outerclass) {
System.out.println("Innerclass的构造方法");
this.outerclass=outerclass;
}
public void func2() {
System.out.println(data3);
System.out.println(outerclass.data1);//就可以调用外部类的非静态成员变量
System.out.println(outerclass.data2);
}
}
}
public class Test {
public static void main(String[] args) {
Outerclass.Innerclass innerclass = new Outerclass.Innerclass(new Outerclass());//将匿名外部类对象传给内部类
innerclass.func2();
}
}
//打印结果是:
//Outerclass的构造方法
//Innerclass的构造方法
//3
//1
//2
复制代码
局部内部类
局部内部类要定义在方法里面,并且不能由public和static修饰
局部内部类很少使用
public class Test {
public void func() {
class A{ //局部内部类
public void test() {
System.out.println("局部内部类的test");
}
}
A a = new A();
a.test();
}
}
public static void main(String[] args) {
Test test = new Test();
test.func();
}
复制代码
局部内部类的字节码文件的命名方式
image-20220514100143274
匿名内部类
public class Test {
static class Person {
public String name;
public int age;
}
public static void main(String[] args) {
new Person() {
public void test() {
System.out.println("就是你了!");
}
}.test();
}
}
复制代码
以上就是4种内部类的语法说明以及代码应用,如有错误,欢迎各位指正!