内部类分为成员内部类(普通内部类)、静态内部类、方法内部类。
一、成员内部类
- 最常见的内部类就是成员内部类,又称普通内部类;
public class Outer {
private int a = 2;// 外部类私有属性
int b = 2;
private void test() { // 外部类方法
System.out.println("Outer.test");
}
// 成员内部类Inner
public class Inner {
int b = 5;// 内部类的成员属性
public void test1() {
System.out.println("Inner.test1");
}
// Inner classes cannot have static declarations
//static int a1 = 3;
/* 普通类内部不能有静态属性和方法
public static void test2() {
System.out.println("Inner.test2");
}*/
public void show() {
// 内部类中的方法可以可以访问外部类的属性和方法
test();
System.out.println("外部类成员变量a:" + a);
// 外部类中属性与内部类中属性变量名相同,要访问外部类变量需要通过 外部名.this.变量名
System.out.println("外部类成员变量b:" + Outer.this.b);
System.out.println("内部类成员变量b:" + this.b);
System.out.println("内部类成员变量b:" + b);
System.out.println("内部类成员变量b:" + b);
}
}
// 测试内部类
public static void main(String[] args) {
Outer cl1 = new Outer();
// 'com.sy.Class.Outer.this' cannot be referenced from a static context
//Inner cl2 = new Inner();
Inner cl2 = cl1.new Inner();
// 外部类的方法只能由外部类对象访问,内部类对象不能访问
cl1.test();
// Cannot resolve method 'test' in 'Inner'
//cl2.test();
// 内部类的方法只能由内部类对象访问,外部类对象不能访问
// 外部类不能访问成员内部类的属性和方法
// Cannot resolve method 'test1' in 'Outer'
//cl1.test1();
cl2.test1();
cl2.show();
}
}
- 1、内部类(Inner)定义在外部类(Outer)的内部,相当于是Outer类的成员变量。Inner类可以使用任意访问修饰符:public、protected、default(friendly)、private。
- 2、Inner类是成员内部类,普通内部类内部不能有静态属性和静态方法。
- 3、Inner类中的方法可以访问Outer类中的属性和方法,不受访问控制符的影响。任意访问修饰符修饰的外部类变量和方法都可以在内部类内部被访问, 外部类方法不能访问内部类的属性和方法。
- 4、定义成员内部类后,必须通过外部类对象创建内部类对象,而不能直接new内部类对象,即内部类 对象名 = 外部类对象.new 内部类()。
//Inner cl2 = new Inner();
Inner cl2 = cl1.new Inner();
- 5、外部类的方法只能由外部类对象访问,内部类对象不能访问。
// 外部类的方法只能由外部类对象访问,内部类对象不能访问
cl1.test();
// Cannot resolve method 'test' in 'Inner'
//cl2.test();
- 6、内部类中的方法只能由内部类对象访问,外部类对象不能访问。 外部类不能访问成员内部类的属性和方法。
// 内部类的方法只能由内部类对象访问,外部类对象不能访问
// 外部类不能访问成员内部类的属性和方法
// Cannot resolve method 'test1' in 'Outer'
//cl1.test1();
cl2.test1();
cl2.show();
- 7、外部类中属性与内部类中属性变量名相同,内部类访问内部类变量直接访问就行,但要访问外部类变量需要通过外部名.this.变量名。
二、静态内部类
- static只能修饰内部类,普通类不允许声明为静态类。
- 内部类被static 修饰,相当于是外部类的一个静态变量。
- 内部类中不能有静态方法。因为静态的对象,在内存中使默认实例化的。内部类可通过外部类直接调用,而不需要实例化对象。
public class Outer {
private int a = 2;// 外部类私有属性
static int b = 2;
private void test() { // 外部类方法
System.out.println("Outer.test");
}
// 静态内部类Inner1
public static class Inner1 {
int b = 5;
private static int c = 6;
public void test1() {
System.out.println("Inner1.test1");
}
public static void test2() {
System.out.println("Inner1.test2");
}
public void show() {
// 静态内部类中的方法可以可以访问外部类的静态属性和方法,不能访问非静态属性和方法
// Non-static method 'test()' cannot be referenced from a static context
//test();
//System.out.println("外部类成员变量a:" + a);
// 外部类中属性与内部类中属性变量名相同,且都是静态属性,要访问外部类变量需要通过 外部名.变量名
System.out.println("外部类成员变量b:" + Outer.b);
System.out.println("内部类成员变量b:" + this.b);
System.out.println("内部类成员变量b:" + b);
}
}
// 测试内部类
public static void main(String[] args) {
Outer cl1 = new Outer();
// Qualified new of static class
//Inner1 cl2 = cl1.new Inner1();
Inner1 cl2 = new Inner1();
// 外部类的方法只能由外部类对象访问,内部类对象不能访问
cl1.test();
// Cannot resolve method 'test' in 'Inner1'
//cl2.test();
// 内部类的方法只能由内部类对象访问,外部类对象不能访问
// 外部类对象不能访问静态内部类的属性和方法
// Cannot resolve method 'test1' in 'Outer'
//cl1.test1();
//cl1.test2();
// 可以通过静态内部类直接访问静态方法,不能访问非静态方法
System.out.println("静态类中静态方法:");
// Non-static method 'test1()' cannot be referenced from a static context
//Inner1.test1();
Inner1.test2();
cl2.test1();
cl2.test2();
cl2.show();
}
}
- 1、Inner类是静态内部类,静态内部类内部有静态属性和静态方法,也可以有非静态成员。
- 2、静态内部类中的方法可以可以访问外部类的静态属性和方法,不能访问非静态属性和方法。
- 3、静态内部类直接new内部类对象,即内部类 对象名 = new 内部类()。
// Qualified new of static class
//Inner1 cl2 = cl1.new Inner1();
Inner1 cl2 = new Inner1();
- 4、外部类的方法只能由外部类对象访问,内部类对象不能访问。
// 外部类的方法只能由外部类对象访问,内部类对象不能访问
cl1.test();
// Cannot resolve method 'test' in 'Inner1'
//cl2.test();
- 5、内部类中的方法只能由内部类对象访问,外部类对象不能访问。 外部类对象不能访问静态内部类的属性和方法。
// 内部类的方法只能由内部类对象访问,外部类对象不能访问
// 外部类不能访问成员内部类的属性和方法
// Cannot resolve method 'test1' in 'Outer'
//cl1.test1();
//cl1.test2();
// 可以通过静态内部类直接访问静态方法,不能访问非静态方法
// Non-static method 'test1()' cannot be referenced from a static context
//Inner1.test1();
Inner1.test2();
cl2.test1();
cl2.test2();
cl2.show();
- 6、外部类中属性与内部类中属性变量名相同,且都是静态属性,要访问外部类变量需要通过外部名.变量名。
三、方法内部类
- 方法内部类定义在外部类的方法中。
public class Outer {
private int a = 2;// 外部类私有属性
static int b = 2;
private void test() { // 外部类方法
System.out.println("Outer.test");
class Inner2 {
// 不能有静态成员
//static int b = 5;
int b = 5;
public void test1() {
System.out.println("Inner2.test1");
}
public void show() {
// 内部类中的方法可以可以访问外部类的属性和方法
test();
System.out.println("外部类成员变量a:" + a);
// 外部类中属性与内部类中属性变量名相同,要访问外部类变量需要通过 外部名.this.变量名
System.out.println("外部类成员变量b:" + Outer.this.b);
System.out.println("内部类成员变量b:" + this.b);
System.out.println("内部类成员变量b:" + b);
}
}
Inner2 cl2 = new Inner2();
// 方法内部类对象不能访问外部类成员
//cl2.test();
cl2.test1();
cl2.show();
}
// 测试内部类
public static void main(String[] args) {
Outer cl1 = new Outer();
// 方法内部类不能在方法外使用
//Inner2 cl2 = new Inner2();
//Inner2 cl2 = cl1.new Inner2();
// 外部类的方法只能由外部类对象访问,内部类对象不能访问
cl1.test();
// 内部类的方法只能由内部类对象访问,外部类对象不能访问
// 外部类不能访问成员内部类的属性和方法
// Cannot resolve method 'test1' in 'Outer'
//cl1.test1();
}
}
- 1、方法内部类只能在外部类的方法中使用,不能在方法外使用。
- 2、方法内部类在方法内使用通过new创建对象。
- 3、方法内部类中的方法可以访问Outer类中的属性和方法,不受访问控制符的影响。任意访问修饰符修饰的外部类变量和方法都可以在内部类内部被访问 。
System.out.println("外部类成员变量a:" + a);
// 外部类中属性与内部类中属性变量名相同,要访问外部类变量需要通过 外部名.this.变量名
System.out.println("外部类成员变量b:" + Outer.this.b);
- 4、方法内部类对象不能访问外部类成员。
Inner2 cl2 = new Inner2();
// 方法内部类对象不能访问外部类成员
//cl2.test();
- 5、方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问权限修饰符和static修饰符。