目录
- 1.什么是内部类
- 2.内部类分类
- 2.1静态内部类
- 2.非静态内部类
- 2.3 局部内部类(几乎不用,大家了解)
- 3.匿名内部类
1.什么是内部类
在Java中,可以将一个类定义在一个类中或者在一个方法中,前者称为内部类,后者称为外部类。
内部类也是封装的一种体现。
class Outclass{//外部类
//静态内部类
static class InnerClass
{
}
}
注意:
1.定义在class类名{}外面的,即使在一个文件中,也不是内部类
class Animal{
}
class Dog
{
}
这只是两个毫无相关的两个类,并不是内部类。
2.内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件。
2.内部类分类
2.1静态内部类
静态内部类就是在一个类中,定义一个由static修饰的类
注意:
1.当我们在内部类中定义了一个方法输出这些变量的时候,外部类的非静态成员变量需要先实例化这个类,在通过这个类对象引用,获得结果。
2.当我们在外部类定义了一个方法,想要输出这些结果,需要先实例化内部类,在通过内部类对象的引用来获取这个变量值。
class Outclass{//外部类
public int data1=1;
private int data2=2;
public static int data5=5;
//静态内部类
static class InnerClass
{
public int data3=1;
private int data4=2;
public static int data6=5;
public void func()
{
Outclass outclass=new Outclass();
System.out.println("==============");
System.out.println(outclass.data1);
System.out.println(outclass.data2);
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
}
}
public void fun()
{
System.out.println("==============");
InnerClass innerClass=new InnerClass();
System.out.println(data1);
System.out.println(data2);
System.out.println(innerClass.data3);
System.out.println(innerClass.data4);
System.out.println(data5);
System.out.println(innerClass.data6);
}
}
public class Test {
public static void main(String[] args) {
Outclass.InnerClass innerClass=new Outclass.InnerClass();
innerClass.func();
Outclass outclass=new Outclass();
outclass.fun();
}
}
2.非静态内部类
非静态内部类就是在一个类的内部,定义一个普通类,不需要static修饰的。
注意:
1.当我们在非静态内部类中,定义了一个方法,想要输出这些变量的话,我们不需要任何的添加,直接就可以输出,但是当我们在内部类中,把外部类的变量值修改了,那么我们输出的就是我们修改过得,内部类的值。
如果我们想要得到,外部类的值,那我们就需要先实例化外部类,通过外部类对象的(Outclass2.this.data1)
这个方法了。
2.当我们在外部类定义了一个方法,想要输出这些结果,需要先实例化内部类,在通过内部类对象的引用来获取这个变量值。
class Outclass2{//外部类
public int data1=1;
private int data2=2;
public static int data5=5;
//非静态内部类
class InnerClass2
{
public int data1=11111;
public int data3=1;
private int data4=2;
public static final int data6=5;
public void func()
{
Outclass outclass=new Outclass();
System.out.println("==============");
System.out.println(data1);
System.out.println(Outclass2.this.data1);
System.out.println(data2);
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
}
}
public void fun()
{
System.out.println("==============");
InnerClass2 innerClass2=new InnerClass2();
System.out.println(data1);
System.out.println(data2);
System.out.println(innerClass2.data3);
System.out.println(innerClass2.data4);
System.out.println(data5);
System.out.println(innerClass2.data6);
}
}
public class Test2 {
public static void main(String[] args) {
Outclass2 outclass2=new Outclass2();
Outclass2.InnerClass2 innerClass2=outclass2.new InnerClass2();
innerClass2.func();
outclass2.fun();
}
}
- 外部类中的任何成员都可以在实例内部类方法中直接访问
- 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
- 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名
称.this.同名成员 来访问- 实例内部类对象必须在先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
2.3 局部内部类(几乎不用,大家了解)
就是在一个类中,定义一个方法,然后在这个方法中,定义一个普通类。
class Outclass3{
public int a=10;
public void func()
{
//局部内部类
class Innerclass
{
public void test()
{
System.out.println("hello!");
}
}
Innerclass innerclass=new Innerclass();
innerclass.test();
}
}
public class Test3 {
public static void main(String[] args) {
Outclass3 outclass3=new Outclass3();
outclass3.func();
}
}
注意:
局部内部类的使用,只能在这个方法中使用,就是说只能在这个方法中进行实例化,然后调用内部类中的属性。
1.局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用
3.匿名内部类
匿名内部类
匿名内部类,就是没有名字的一种嵌套类。它是Java对类的定义方式之一。
为什么要使用匿名内部类?
在实际开发中,我们常常遇到这样的情况:一个接口的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余。
interface IA
{
void func();
}
public class Test4 {
public static void main(String[] args) {
//匿名内部类
new IA(){
@Override
public void func() {
System.out.println("hello!!!");
}
}.func();
}
}
我们为了实现某一个方法,就需要先实现一个接口,但是如果我们想使用这个方法的话就需要去实例化一个对象,太麻烦,所以我们就通过new 接口(){ };这样的格式,去定义一个匿名内部类,最后调用这个方法就可以了。
这个就是匿名内部类的格式了。