一、内部类的概念
内部类的是定义在另一个类中的类
一般分为:
- 本地内部类
- 实例内部类
- 静态内部类
- 匿名内部类
二、内部类的分类
1.本地内部类
定义在方法当中的类。
public class TestDemo {
public void func(){
class Test{
public int a;
}
}
本地内部类,我们用得比较少,我们写本地内部类的时候一定要谨慎。
同时,本地内部类有一个很大的缺点:只能在当前方法中使用。
2.实例内部类
实例内部类是指没有用 static 修饰的内部类,有的地方也称为非静态内部类。
简单示例如下:
public class OuterClass {
class InnerClass {
}
}
上面的InnerClass就是实力内部类了。
实例内部类的注意事项有以下几点,我们通过实例来一一了解:
- 在实例内部类中不能定义一个静态的成员变量,如果非要定义,只能定义一个静态常量,也就是用final修饰。
class OuterClass{
class InnerClass{
public int data4=4;
private int data5 = 5;
public static final int data6 = 6;
}
}
- 我们如何实例化 实例内部类的对象?
外部类名.内部类名 变量 = 外部类对象的引用.new 内部类();
class OuterClass{
class InnerClass{
public int data4=4;
private int data5 = 5;
public static final int data6 = 6;
}
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
}
- 实例内部类当中,如果包含了和外部类同名的成员变量,我们如何在实例内部类中访问?
我们可以通过外部类的this来访问。注意:我们实例内部类当中包含了两个this,一个是外部类的this,一个是内部类的this。
class OuterClass{
public int data1= 1;
class InnerClass{
public int data1=999;
public InnerClass(){
System.out.println("不带参数的内部类构造方法");
}
public void test(){
System.out.println(OuterClass.this.data1);
System.out.println(this.data1);
}
}
}
public class TestDemo {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.test();
}
}
3.静态内部类
实例内部类是指用 static 修饰的内部类
public class OuterClass {
static class InnerClass {
}
}
静态内部类的一些问题:
- 如何访问外部类的普通成员变量?
静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。
class OuterClass2{
public int data1 = 1;
private int data2 = 2;
public static int data3 = 3;
static class InnerClass{
public int data4 = 4;
private int data5 = 5;
public static int data6 = 6;
public OuterClass2 out;
public InnerClass(OuterClass2 out){
this.out = out;
}
public void test(){
System.out.println(out.data1);
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
System.out.println("InnerClass::test()");
}
}
- 如何实例化静态成员变量?
外部类名.内部类名 变量 =new 外部类对象的引用.内部类(变量);
public static void main(String[] args) {
OuterClass2 outerClass2 = new OuterClass2();
OuterClass2.InnerClass innerClass = new OuterClass2.InnerClass(outerClass2);
innerClass.test();
}
打印结果:
3.匿名内部类
名内部类就是一个没有显式的名字的内部类。 匿名内部类没有类名,因此就不可能有构造函数,不能创建对象。
语法一:
new 实现接口()
{
}
语法二:
new 父类构造器(实参列表)
{
}
实例:
class Test{
public void test(){
System.out.println("test()haha!");
}
}
public class TestDemo2 {
public static void main(String[] args) {
new Test(){
@Override
public void test(){
System.out.println("我是重写的test方法");
}
}.test();
}
就是定义了一个类Test,在类里定义了一个test方法。调用他的实例方法test()。
然后调用它的test()方法。
在调用test()方法的同时,重写了test()方法,所以打印结果为:我是重写的test方法。
输出结果: 所以,匿名内部类的最大好处就是可以简化我们代码的书写。
总结
为什么需要使用内部类呢? 其主要原因有以下三点: ?内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据。
?内部类可以对同一个包中的其他类隐藏起来。
?当想要定义一个回调函数且不想编写大量代码时,使用匿名 (anonymous) 内部类比较便捷。
|