Java - 内部类

内部类分为4种

成员内部类(非静态内部类)
局部内部类
静态内部类
匿名内部类

成员内部类(member inner class)非静态内部类

定义在外部类里面不使用static修饰
成员内部类相当于外部类的成员,内部类可以访问外部类一切成员
编译之后生成.class文件: OutterClass$InnerClass.class 
内部类不可以有静态成员
案例
package com.itlwc;

class OutterClass {
	int x = 100;
	class InnerClass {
		int x = 50;

		public void show() {
			//使用预定义对象引用this
			System.out.println("调用外部类成员x = " + OutterClass.this.x);
			System.out.println("调用成员内部类成员x = " + this.x);
		}
	}
}

public class Test {
	public static void main(String[] args) {
		//生成对象的方法
		OutterClass.InnerClass ocic = new OutterClass().new InnerClass();
		ocic.show();
	}
}
/*
打印结果:
	调用外部类成员x = 100
	调用成员内部类成员x = 50
*/

局部内部类(local inner class)

定义在方法中
局部内部类只能访问局部final的成员

案例

package com.itlwc;

class OutterClass {
	public void getInnerClass() {
		// 局部内部类只能访问final的变量
		final int x = 0;
		class InnerClass {
			public void show() {
				System.out.println("局部内部类的方法" + x);
			}
		}
		InnerClass ic = new InnerClass();
		ic.show();
	}
}

public class Test {
	public static void main(String[] args) {
		OutterClass oc = new OutterClass();
		oc.getInnerClass();
	}
}
/*
打印结果:
	局部内部类的方法0
*/

静态内部类(static inner class)

定义在类的里面使用static关键字
编译之后生成.class文件: OutterClass$InnerClass.class
静态内部类只能访问静态成员
静态内部类不能使用this
案例
package com.itlwc;

class OutterClass {
	static class InnerClass {
		public void show() {
			System.out.println("静态内部类的方法");
		}
	}
}

public class Test {
	public static void main(String[] args) {
		//生成对象的方法
		OutterClass.InnerClass oi = new OutterClass.InnerClass();
		oi.show();
	}
}
/*
打印结果:
	静态内部类的方法
*/

非静态内部类和静态内部类的区别

非静态内部类与外部类对象成员存在共享关系,是外部类的组成部分,用来辅助工作
静态内部类与外部类之间没有这样的关系,静态内部类已经脱离了外部类的控制,
	static关键字只是说明创建对象不依赖外部类的引用的存在,并不是说这个类是静态的

匿名内部类(anonymous inner class)

定义:没有名字的内部类
匿名内部类没有名称,因此匿名内部类在声明类的同时也创建了对象
匿名内部类没有class,名字,extends,implements,构造方法,
	但它会隐式继承一个父类或者实现一个接口,这两个不能同时(这个是内部类很重要的特点)
因为匿名内部类没有名称,没办法声明匿名内部类类型的引用,
	因此匿名内部类中的成员只能内部使用
匿名内部类对象的使用都是通过多态进行的,
	如果匿名内部类重写了父类方法,可以通过多态让父类的引用调用匿名内部类的方法
	(案例一)
匿名内部类编译后也是一个独立的类文件,
	由于没有名字,使用数字代替,如 OutClass$1.class
匿名内部类对象初始化的代码可以写在非静态语句块中
	(案例二)
案例一

package com.itlwc;

class Father {
	public void show() {
		System.out.println("Father类的方法");
	}
}

public class Test {
	public static void main(String[] args) {
		// 定义匿名内部类并创建对象
		Father f = new Father() {
			// 重写了父类的方法
			public void show() {
				System.out.println("匿名内部类的方法");
			}
		};
		// 通过多态调用了父类的引用调用了子类的对象
		f.show();
	}
}
/*
打印结果:
	匿名内部类的方法
*/
案例二

package com.itlwc;

abstract class Father {
	int age;

	abstract void show();
}

public class Test {
	public static void main(String[] args) {
		// 定义匿名内部类并创建对象
		Father f = new Father() {
			// 非静态代码块中对成员age进行初始化
			{
				age = 18;
			}

			// 实现父类的方法
			public void show() {
				System.out.println("年龄 = " + age);
			}
		};
		// 通过多态使用父类的引用调用子类对象
		f.show();
	}
}
/*
打印结果:
	年龄 = 18
*/

有名字的内部类和匿名内部类的区别

如果有两个或者两个方法会使用该类,建议使用内部类
如果只有一个方法使用该类,建议使用匿名内部类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值