文章目录
- 1.内部类
- 2.成员内部类
- 3.局部内部类
- 4.静态内部类
- 5.匿名内部类
- 6.总结
今日提要:内部类
1.内部类
定义:Java在一个类中定义一个类,这个类被称为内部类,定义这个内部类所在的类叫做外部类;
2.成员内部类
定义:
- 在一个类中定义的变量叫做成员变量,定义的方法叫做成员方法,定义的类叫做成员内部类;
- 成员内部类可以访问外部类的所有成员变量和成员方法,而外部类也可以访问成员内部类的变量和方法;
- 对象的创建:外部类名.内部类名 变量名 = new 外部类名().new 内部类名();;
- 上代码:
public class ExternalClass {//外部类//外部类成员属性int x = 10;String a = "这是个外部类的成员变量";//外部类成员方法public void testExternalOne() {System.out.println("这是个外部类的成员方法 testExternalOne");}public void testExternalTwo() {InsideClass ins = new InsideClass();System.out.println("外部类调用内部类的成员变量: " + "内部类变量 xx = " + ins.xx + " , " + "内部类变量 aa = " + ins.aa);System.out.print("外部类调用内部类的成员方法: ");ins.testInsideOne();}//成员内部类class InsideClass{//成员内部类//内部类成员属性int xx = 20;String aa = "这是个内部类的成员变量";//内部类成员方法public void testInsideOne() {System.out.println("这是个内部类的成员方法 testInsideOne"); }public void testInsideTwo() {System.out.println("内部类调用外部类的成员变量: " + "外部类变量 x = " + x + " , " + "外部类变量 a = " + a);System.out.print("内部类调用外部类的成员方法: ");testExternalOne();}}public static void main(String[] args) {ExternalClass test0 = new ExternalClass();test0.testExternalOne();test0.testExternalTwo();System.out.println();ExternalClass.InsideClass test1 = new ExternalClass().new InsideClass();test1.testInsideOne();test1.testInsideTwo();}
}
运行结果:
这是个外部类的成员方法 testExternalOne
外部类调用内部类的成员变量: 内部类变量 xx = 20 , 内部类变量 aa = 这是个内部类的成员变量
外部类调用内部类的成员方法: 这是个内部类的成员方法 testInsideOne这是个内部类的成员方法 testInsideOne
内部类调用外部类的成员变量: 外部类变量 x = 10 , 外部类变量 a = 这是个外部类的成员变量
内部类调用外部类的成员方法: 这是个外部类的成员方法 testExternalOne
- 外部类访问内部类的成员的时候,需要先创建对象,内部类访问外部类成员的时候,可以直接访问;
- 还有需要重点注意的是,如果内外部类相互调用,极易产生递归调用,代码陷入死循环,别问我是怎么知道的
- 另外
ExternalClass.InsideClass test1 = new ExternalClass().new InsideClass();
等价于ExternalClass test0 = new ExternalClass(); ExternalClass.InsideClass test1 = test0.new InsideClass();
3.局部内部类
定义:
- 局部内部类(方法内部类),它定义在方法内;
- 局部内部类可以访问外部类的所有成员变量和成员方法;
- 局部内部类的成员变量和成员方法,只能在定义这个局部内部类的方法中访问;
- 上代码:
public class ExternalClass {//外部类//外部类成员变量int x = 10;String a = "你好!我是个外部类的成员变量";//外部类成员方法public void testExternalOne() {System.out.println("你好!我是外部类成员方法:testExternalOne();");
// InsideClass i = new InsideClass();//局部内部类在外部类的其它成员方法中不可见}public void testExternalTwo() {//外部类成员方法中的变量int y = 20;String b = "你好!我是外部类成员方法中的变量";//定义局部内部类class InsideClass{//局部内部类成员变量int xx = 30;String aa = "你好!我是局部内部类的成员变量";//局部内部类成员方法void testInsideOne() {System.out.println("你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员变量:" + "外部类成员变量x = " + x + " , " + "外部类成员变量a = " + a);System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员方法:");testExternalOne();System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问定义我的外部类的成员方法的成员变量:");System.out.println("定义局部内部类的外部类成员方法的成员变量y = " + y + " , " + "定义局部内部类的外部类成员方法的成员变量b = " + b);System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问局部内部类的成员变量:");System.out.println("局部内部类的成员变量xx = " + xx + " , " + "局部内部类的成员变量aa = " + aa);} }//定义局部内部类的外部类成员方法访问局部内部类,需要先创建局部内部类对象,才能访问局部内部类成员InsideClass i = new InsideClass();i.testInsideOne();System.out.print("你好!我是定义局部内部类的外部类成员方法testExternalTwo(),我将访问局部内部类的成员变量:");System.out.println("局部内部类的成员变量xx = " + i.xx + " , " + "局部内部类的成员变量aa = " + i.aa);} public static void main(String[] args) {ExternalClass e = new ExternalClass();e.testExternalTwo();}
}
运行结果:
你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员变量:外部类成员变量x = 10 , 外部类成员变量a = 你好!我是个外部类的成员变量
你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员方法:你好!我是外部类成员方法:testExternalOne();
你好!我是局部内部类的成员方法testInsideOne(),我将访问定义我的外部类的成员方法的成员变量:定义局部内部类的外部类成员方法的成员变量y = 20 , 定义局部内部类的外部类成员方法的成员变量b = 你好!我是外部类成员方法中的变量
你好!我是局部内部类的成员方法testInsideOne(),我将访问局部内部类的成员变量:局部内部类的成员变量xx = 30 , 局部内部类的成员变量aa = 你好!我是局部内部类的成员变量
你好!我是定义局部内部类的外部类成员方法testExternalTwo(),我将访问局部内部类的成员变量:局部内部类的成员变量xx = 30 , 局部内部类的成员变量aa = 你好!我是局部内部类的成员变量
- 局部内部类访问外部类成员的时候,可以直接访问,定义局部内部类的外部类成员方法访问局部内部类的成员的时候,需要先创建对象,外部类的其它成员方法无法访问局部内部类;
4.静态内部类
定义:
- 静态内部类,就是用static关键字修饰的成员内部类;
- 静态内部类,只能访问外部类的静态成员;
- 上代码
public class ExternalClass {// 外部类// 外部类成员属性static int x = 10;static String a = "这是个外部类的静态成员变量";// 外部类成员方法public static void testExternalOne() {System.out.println("这是个外部类的静态成员方法 testExternalOne");}public void testExternalTwo() {InsideClass ins = new InsideClass();System.out.println("外部类调用静态内部类的成员变量: " + "静态内部类变量 xx = " + ins.xx + " , " + "静态内部类变量 aa = " + ins.aa);System.out.print("外部类调用静态内部类的成员方法: ");ins.testInsideOne();}// 成员静态内部类static class InsideClass {// 成员静态内部类// 静态内部类成员属性int xx = 20;String aa = "这是个静态内部类的成员变量";// 静态内部类成员方法public void testInsideOne() {System.out.println("这是个静态内部类的成员方法 testInsideOne");}public void testInsideTwo() {System.out.println("静态内部类调用外部类的静态成员变量: " + "外部类静态变量 x = " + x + " , " + "外部类静态变量 a = " + a);System.out.print("静态内部类调用外部类的静态成员方法: ");testExternalOne();}}public static void main(String[] args) {ExternalClass test0 = new ExternalClass();test0.testExternalOne();test0.testExternalTwo();System.out.println();ExternalClass.InsideClass test1 = new ExternalClass.InsideClass();test1.testInsideOne();test1.testInsideTwo();}}
运行结果:
这是个外部类的静态成员方法 testExternalOne
外部类调用静态内部类的成员变量: 静态内部类变量 xx = 20 , 静态内部类变量 aa = 这是个静态内部类的成员变量
外部类调用静态内部类的成员方法: 这是个静态内部类的成员方法 testInsideOne这是个静态内部类的成员方法 testInsideOne
静态内部类调用外部类的静态成员变量: 外部类静态变量 x = 10 , 外部类静态变量 a = 这是个外部类的静态成员变量
静态内部类调用外部类的静态成员方法: 这是个外部类的静态成员方法 testExternalOne
- 创建静态内部类的对象语法:外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名();;
5.匿名内部类
- 匿名内部类,没有名字;
- 用以简化接口参数传递时的代码
- 上代码
interface OneInterface {// 创建一个接口void show();
}class InterfaceImpl implements OneInterface {@Overridepublic void show() {System.out.println("InterfaceImpl类实现了接口OneInterface");}
}class TestInterface {void test(OneInterface oneInterface) {System.out.println("这只是一个测试方法");oneInterface.show();}
}public class Test00 {public static void main(String[] args) {TestInterface t1 = new TestInterface();OneInterface o1 = new InterfaceImpl();t1.test(o1);System.out.println();TestInterface t2 = new TestInterface();t2.test(new OneInterface() {// 创建匿名内部类实例化接口@Overridepublic void show() {System.out.println("匿名内部类实现了接口OneInterface");}});}
}
运行结果:
这只是一个测试方法
InterfaceImpl类实现了接口OneInterface这只是一个测试方法
匿名内部类实现了接口OneInterface
- 如果方法含有接口类参数的时候,无需单独书写实例化接口的类,而只需要通过匿名内部类直接实例化接口就可以了,简化了代码的书写;
- 创建匿名内部类语法:new 父接口() {//匿名内部类实例化接口代码块}
6.总结
- 成员内部类结合接口的使用,解决了Java单继承规则下的,多继承实例应用;
- 局部内部类、静态内部类,更多的是为强化代码的访问范围,主要用于提高代码的安全性;
- 匿名内部类,主要用于简化接口实现代码;