Java 实例内部类

164 阅读3分钟

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战

实例内部类是位于其他类中的类,且没有用 static 修饰,也称作非静态内部类。

public class Outer {
	class Inner {
		// 实例内部类
	}
}

实例内部类的使用:

1)在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例。

public class Outer {
	class Inner1 {
	}
	
	Inner1 i = new Inner1(); // 不需要创建外部类实例
	
	public void method1() {
		Inner1 i = new Inner1(); // 不需要创建外部类实例
	}
	
	public static void method2() {
		Inner1 i = new Outer().new inner1(); // 需要创建外部类实例
	}
	
	class Inner2 {
		Inner1 i = new Inner1(); // 不需要创建外部类实例
	}
}

class OtherClass {
	Outer.Inner i = new Outer().new Inner(); // 需要创建外部类实例
}

2)在实例内部类中,可以访问外部类的所有成员。 如果有多层嵌套,则内部类可以访问所有外部类的成员。

public class Outer {
	public int a = 100;
	static int b = 100;
	final int c = 100;
	private int d = 100;
	public String method1() {
		return "实例方法1";
	}
	public static String method2() {
		return "静态方法2";
	}
	class Inner {
		int a2 = a + 1; // 访问public的a
		int b2 = b + 1; // 访问static的b
		int c2 = c + 1; // 访问final的c
		int d2 = d + 1; // 访问private的d
		String str1 = method1(); // 访问实例方法method1
		String str2 = method2(); // 访问静态方法method2
	}
	public static void main(String[] args) {
		Inner i = new Outer().new Inner(); // 创建内部类实例
		System.out.println(i.a2); // 输出101
		System.out.println(i.b2); // 输出101
		System.out.println(i.c2); // 输出101
		System.out.println(i.d2); // 输出101
		System.out.println(i.str1); // 输出实例方法1
		System.out.println(i.str2); // 输出静态方法2
	}
}

3)在外部类中不能直接访问内部类的成员,而必须通过内部类的实例去访问。如果类 A 包含内部类 B,类 B 中包含内部类 C,则在类 A 中不能直接访问类 C,而应该通过类 B 的实例去访问类 C

虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。

class Circle {
    private double radius = 0;
 
    public Circle(double radius) {
        this.radius = radius;
        getDrawInstance().drawSahpe();   //必须先创建成员内部类的对象,再进行访问
    }
     
    private Draw getDrawInstance() {
        return new Draw();
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println(radius);  //外部类的private成员
        }
    }
}

4)外部类实例与内部类实例是一对多的关系,也就是说一个内部类实例只对应一个外部类实例,而一个外部类实例则可以对应多个内部类实例。

5)如果实例内部类 B 与外部类 A 包含有同名的成员 t,则在类 Btthis.t 都表示 B 中的成员 t,而 A.this.t 表示 A 中的成员 t

public class Outer {
	int a = 10;
	class Inner {
		int a = 20;
		int b1 = a;
		int b2 = this.a;
		int b3 = Outer.this.a;
	}
	public static void main(String[] args) {
		Inner i = new Outer().new Inner();
		System.out.println(i.b1); // 输出20
		System.out.println(i.b2); // 输出20
		System.out.println(i.b3); // 输出10
	}
}

当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法

6)在实例内部类中不能定义 static 成员,除非同时使用 finalstatic 修饰。