内部类
1 内部类的概念及其分类
定义:当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服 务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
分类:根据内部类定义的位置不同,一般可以分为以下几种形式:
- 成员内部类(实例内部类:未被static修饰的成员内部类 和 静态内部类:被static修饰的成员内部类) 。
- 局部内部类(不谈修饰符)、匿名内部类。
2 内部类的定义方式
class OuterClass{ //定义一个内部类 class InnerClass{ } }
当然,内部类可以进行嵌套:建议嵌套层次不要太多。
class OuterClass{ class InnerClass{ class InnerClass1{ class InnerClass2{ ...... } } } }
注意:
1.定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类。例如:
public class A{ } class B{ }
此处的A和B就是两个单独的类。
2.内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件。
3 内部类的用法
3.1实例内部类
概念:未被static修饰的成员内部类。
class OuterClass{ //外部类的成员 int data1 =1; static int data2 = 2; class InnerClass { //内部类的成员 int data3 = 3; static final int data4 =4; public void fun() { System.out.println(data3); } } }
3.1.1 实例内部类的注意点:
1.在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员,例如:
class OuterClass{ //外部类的成员 private int data1 =1;//被privat修饰的成员 static int data2 = 2; class InnerClass { //内部类的成员 int data3 = 3; static final int data4 =4; public void fun() { System.out.println(data1);//访问外部类中被private修饰的成员 System.out.println(data2); } } }
2.在实例内部类中不能创建静态成员变量和静态成员方法,如果一定要创建静态成员变量的话,该成员必须要被static final修饰并且初始化。不能先定义data4再赋值,这里要同时进行。
那么这里被final修饰代表什么意思呢?其实被static修饰的变量就是常量,其值不能被更改。
当我们创建好了一个内部类时,我们在public类中如何访问这内部类中的成员呢?
3.1.12访问内部类的元素
我们这里只讲嵌套了一层内部类的情况,访问实例内部类成员的方法有两种。
方法一:
public class Test{ public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); System.out.println(innerClass.data3);//访问内部类的成员 } }
下面我们将这段代码进行拆解讲解:
这段代码用于创建一个外部内的引用变量 outerClass。
OuterClass outerClass = new OuterClass();
再通过outerClass这个引用变量创建一个内部类的引用。即:
//语法格式:类型(OuterClass.InnerClass) 变量名(innerClass) = 外部类的引用(outerClass).new 内部类(InnerClass()); OuterClass.InnerClass innerClass = outerClass.new InnerClass();
注意事项:
1.当内部类和外部类的有相同变量名的成员变量时,在内部类中访问这个变量时,优先访问的是内部类的变量。例如:
class OuterClass{ int data3 =33; class InnerClass { int data3 = 3; public void fun() { System.out.println(data3); } } } public class Test{ public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.fun(); } }
运行结果:
倘若我们想要访问的是外部类的那个变量,只需将
public void fun() { System.out.println(data3); }
改成
public void fun() { //语法格式:外部类.this.变量名 System.out.println(OuterClass.this.data3); }
即可打印外部类的那个变量。
2:当我们想要在外部类中访问内部类的成员时,要先在外部类中创建实例内部类对象,例如:
class OuterClass{ int data1 =1; InnerClass innerClass = new InnerClass();//在外部类中创建实例内部类对象 public void print() { System.out.println(innerClass.data2);//访问内部类 } class InnerClass { int data2 = 2; } } public class Test3{ public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.print(); } }
运行结果:
方法二:
public class Test{ public static void main(String[] args) { //语法格式 OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();//实例化内部类 System.out.println(innerClass.data4);//访问内部类的成员 } }
3.2 静态内部类
概念:被static修饰的内部成员类称为静态内部类。
定义方式(这里我们只讲嵌套了一层内部类的情况):
class OuterClass{ //定义了一个静态内部类 static class InnerClass{ …… } }
- 当我们想要获取静态内部类的成员变量时,可以不用创建外部类对象,可以直接创建内部类对象进行访问。
- 语法格式如下:
- //类型(OuterClass.InnerClass).变量名 = new 类型(OuterClass.InnerClass)();
- OuterClass.InnerClass innerclass = new OuterClass.InnerClass();
class OuterClass{ public static int data1 = 1; int data2 = 2; public static void functionA() { System.out.println("这是一个外部类中的静态方法"); } public void functionB() { System.out.println("这是一个外部类中的非静态方法"); } static class InnerClass{ int data3 = 3; public void fun(){ //System.out.println(data2);//访问外部类中的非静态成员,会报错 System.out.println(data1);//访问外部类中的实例成员,正常执行 functionB();//调用外部类中的非静态方法,会报错 functionA();//调用外部类中的静态方法,正常执行 } } } public class test { public static void main(String[] args) { OuterClass.InnerClass innerclass = new OuterClass.InnerClass();//创建内部类对象 innerclass.fun(); OuterClass outerclass = new OuterClass(); System.out.println(outerclass.data2);//通过创建外部类对象访问非静态成员 } }
若一定要访问外部类中的非静态成员,只能通过创建外部类的对象进行访问。例如上述代码的28-29行:
OuterClass outerclass = new OuterClass(); System.out.println(outerclass.data2);//通过创建外部类对象访问非静态成员
3.3 局部内部类:
概念:定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。
定义方式:
public class OutClass { int a = 10; public void method(){ int b = 10; // 局部内部类:定义在方法体内部 // 不能被public、static等访问限定符修饰 class InnerClass{ public void methodInnerClass(){ System.out.println(a); System.out.println(b); } } // 只能在该方法体内部使用,其他位置都不能用 InnerClass innerClass = new InnerClass(); innerClass.methodInnerClass(); } public static void main(String[] args) { // OutClass.InnerClass innerClass = null; 编译失败 } }
注意:
- 局部内部类只能定义在方法内部,并且不能被访问限定修饰符修饰。
- 局部内部类只能在方法体内部使用。
本章的内容就到这里啦,若有不足,欢迎评论区指正,最后,希望大佬们多多三连吧,下期见!