在Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的 内部类一般来说包括这四种:静态内部类、匿名内部类、成员内部类和局部内部类,下面我们一一介绍。
目录
四种内部类
一. 成员内部类
二. 静态内部类
三. 匿名内部类
四. 局部内部类
成员内部类,顾名思义,是作为对象的一个成员来定义的类。
下面给出代码例子:
public class Test2 {
public int a = 0;
public double b = 0.0;
//成员内部类
class T1{
public int i;
}
public static void main(String[] args) {
//成员内部类依赖外部类的对象,因为他是一个外部类的一个成员
//T1 t = new T();
Test2 test2 = new Test2();
//这样也是不行的,没办法new T1();
//new T1();
}
}
成员内部类作为外部类的一个属性是不能脱离外部类实例化的所以可见上面代码中的 new T() 都无法成功。
我们直接给出代码例子
public class Test2 {
public int a = 0;
public double b = 0.0;
//静态内部类 == 成员内部类 + static
static class T2{
public int i;
}
public static void main(String[] args) {
// 静态内部类
// 静态内部类类似于类属性,可以直接初始化
T2 t2 = new T2();
}
}
静态内部类 == 成员内部类 + static
静态内部类相当于外部类的一个类属性,可以脱离外部类实例,直接初始化。
匿名内部类的定义,是在一个方法或是代码块中定义的类,并且没有显示申明类的名称,比如这样:
public class Test2 {
public int a = 0;
public double b = 0.0;
public void fun(){
System.out.println("哈哈哈");
}
public void fun1(){
System.out.println(a);
}
public static void main(String[] args) {
// 匿名内部类
// 定义在方法或者代码块里
// 这个类没有名字,是Test2类的一个子类,继承于Test2
Test2 test2 = new Test2() {
//可以重写方法
@Override
public void fun(){
System.out.println("内部类");
}
//也可以添加属性,但是这个属性想在外部访问的时涉及向下转型
//在外部访问的时候是通过指向父类的引用访问的
//就不可以向下转型,因为向下转型需要子类引用(但是子类的名字不知道)
//所以在外部访问没有太大意义
//但是可以在这个类的内部访问这个属性
public int c = 1;
//在类内部访问该属性
@Override
public void fun1(){
System.out.println("访问内部类新添加的属性 c " + c);
}
};
System.out.println("通过内部类访问外部类的属性" + test2.a);
//直接外部访问不可行
//System.out.println(test2.c);
//调用方法在类内部访问该属性
test2.fun1();
//调用重写后的方法
test2.fun();
}
}
参考上面代码,匿名内部类没有名字,它是外部类的一个子类,所以它继承了外部类的所有的属性和方法。
我们可以在这个内部类中重写外部类的方法,这是匿名内部类的主要用途。
我们也可以在这个内部类中添加新的属性和方法,但是在外部访问就没有那么容易了。
由于我们不知道内部类的名字,所以无法用内部类引用的类型指向内部类实例(内部类 引用 = new 内部类() 向这样的代码无法办到),所以只能用父类引用指向子类实例,就是所谓的向上转型,根据 Java 多态的语法,无法用父类的引用访问到子类新添加的属性和方法。
我们现在来解释一下上面的代码:
匿名内部类是外部类的一个子类,我们在这个内部类中重写 fun() 和 fun1() 方法,而且添加了新的属性 c ,
根据 Java 中多态的语法( Test2 test2 = new Test2(){......} 这一句涉及到向上转型),我们通过指向内部类(这个内部类同时是子类)的引用来调用重写后的 fun() 和 fun1() 方法,而在 fun1() 中,我们访问了新添加的属性,所以代码的执行结果为:
联想到局部变量,局部内部类的作用域也是和局部变量类似,是在方法或是代码块中定义。
下面给出代码例子:
public class Test2 {
public int a = 0;
public double b = 0.0;
public void fun(){
System.out.println("哈哈哈");
}
public static void main(String[] args) {
//局部内部类 定义到方法内部作为局部变量
class T3{
//属性,方法等
public int a = 10;
public void fun(){
System.out.println("hahaha");
}
}
T3 t3 = new T3();
t3.fun();
System.out.println(t3.a);
}
}
局部内部类 定义到方法内部作为局部变量,可以在它的作用域范围进行实例化。
上面代码中,我们在类 T3 中写的一个 fun() 方法,注意这里不是方法重写,因为 T3 和 Test2 没有父子关系。
今天的分享就到这里,需要重点掌握的是匿名内部类,这在今后的开发中也比较常用。希望大家多多评论,相互提高。