内部类
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.1 访问内部类的元素
我们这里只讲嵌套了一层内部类的情况,访问实例内部类成员的方法有两种。
方法一:
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; 编译失败
}
}
注意:
- 局部内部类只能定义在方法内部,并且不能被访问限定修饰符修饰。
- 局部内部类只能在方法体内部使用。
本章的内容就到这里啦,若有不足,欢迎评论区指正,最后,希望大佬们多多三连吧,下期见!