10.java内部类
包含在类中的内就是内部类,包含内部类的类是外部类。
内部类有四种:成员内部类,方法内部类,静态嵌套类,匿名内部类
1.成员内部类
相当于java类中的成员变量基本结构:
1
2
3
4public class TestClass{ public class InnerClass { } }
内部类编译后会形成一个新的字节码文件【外部类类名$内部类类型.class】
1.1成员内部类用法
(1)成员内部类可以使用任意的访问限制修饰符;
public class TestClass {
//成员内部类可以使用任意的访问限制修饰符
public class InnerClass{ }
protected class InnerClass1{ }
class InnerClass2{ }
private class InnerClass3{ }
}
(2)成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素
代码测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class TestClass { //成员内部类 public class InnerClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素 int id=10;//成员内部类实例变量 //static String name="zhangsan";//报错,成员内部类不能有静态变量 public void Innermethod(){ System.out.println("成员内部类的实例方法"); } public InnerClass(){ System.out.println("成员内部类的构造方法"); } //public static void staticInnermethod(){}//报错,成员内部类不能有静态方法 } }
(3)成员内部类中的构造方法可以访问其他的构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】
(4)成员内部类中的实例方法可以访问构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】。
(5)成员内部类中的构造方法可以访问外内部类的构造方法,实例方法/变量,类方法/变量。
(6)成员内部类中的实例方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。
(7)外内部类中的构造方法/实例法可以访问成员内部类的构造方法,实例方法/变量,外内部类中的类方法不能访问成员内部类。
外部类访问内部内时,用.this和省略都会错,只能对象访问。
外内部类中的类方法,new内部类对象报错
(8)其他类中是可以访问成员内部类的,需要依赖外部类对象【new外部类类名().new 静态嵌套类名()】,注意访问限制修饰符。
也是不能用this.和省略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92public class TestClass { public String name="wuwei";//外部类实例变量 public static String lsp="sss";//外部类静态成员变量 public void outMethod(){ System.out.println("外部类的实例方法"); new InnerClass(); new InnerClass().id=1001; new InnerClass().Innermethod1(); //InnerClass.this.id=1000;报错 //id=1000;报错 } public static void staticOutMethod(){ System.out.println("外部类的静态方法"); //new InnerClass();报错 } public TestClass(){ System.out.println("外部类的构造方法"); new InnerClass(); new InnerClass().id=1001; new InnerClass().Innermethod1(); //InnerClass.this.id=1000;报错 //id=1000;报错 } //成员内部类 public class InnerClass{ //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素 int id=10;//成员内部类实例变量 //static String name="zhangsan";//报错,成员内部类不能有静态变量 public void Innermethod1(){ System.out.println("成员内部类的实例方法1"); new TestClass();//访问外部类 new TestClass().name="zj";//访问外部类实例变量方法1 TestClass.this.name="zj";//访问外部类实例变量方法2 new TestClass().lsp="sss";//访问外部类静态变量 TestClass.this.staticOutMethod(); TestClass.this.lsp="sss"; new TestClass().staticOutMethod();//访问外部类静态方法 //TestClass.this表示外部类这个当前类 new TestClass().outMethod();//访问外部类实例方法,方法1 TestClass.this.outMethod();//访问外部类实例方法,方法2 //还可以省略 outMethod(); name="zj"; } public void Innermethod2(){ System.out.println("成员内部类的实例方法2"); InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象 ic.id=11;//访问实例变量方式1 this.id=12;//访问实例变量方式2 id=13;//访问实例变量方式3,this和对象可以省略, ic.Innermethod1();//访问实例方法1 this.Innermethod1();//访问实例方法2 Innermethod1();//访问实例方法3 } public InnerClass(){ System.out.println("成员内部类的构造方法"); InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象 ic.id=11;//访问实例变量方式1 this.id=12;//访问实例变量方式2 id=13;//访问实例变量方式3,this和对象可以省略, ic.Innermethod1();//访问实例方法1 this.Innermethod1();//访问实例方法2 Innermethod1();//访问实例方法3 } //public static void staticInnermethod(){}//报错,成员内部类不能有静态方法 public InnerClass(String name){ System.out.println("成员内部类有参数的构造方法"); InnerClass ic1=new InnerClass();//访问其他构造方法,内部类的对象 ic1.id=11;//访问实例变量方式1 this.id=12;//访问实例变量方式2 id=13;//访问实例变量方式3,this和对象可以省略, ic1.Innermethod1();//访问实例方法1 this.Innermethod1();//访问实例方法2 Innermethod1();//访问实例方法3 new TestClass();//访问外部类 new TestClass().name="zj";//访问外部类实例变量方法1 TestClass.this.name="zj";//访问外部类实例变量方法2 new TestClass().lsp="sss";//访问外部类静态变量 TestClass.this.staticOutMethod(); TestClass.this.lsp="sss"; new TestClass().staticOutMethod();//访问外部类静态方法 //TestClass.this表示外部类这个当前类 new TestClass().outMethod();//访问外部类实例方法,方法1 TestClass.this.outMethod();//访问外部类实例方法,方法2 //还可以省略 outMethod(); name="zj"; } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class OtherClass { public void otherMethod(){ System.out.println("其他类的实例方法"); //试着访问另一个类里面的内部类变量和方法 //先访问外部类,再去内部类 new TestClass(); new TestClass().new InnerClass(); //相当于先new外部类,TestClass tc=new TestClass(); //在new内部类,TestClass.InnerClass tci=tc.new InnerClass(); TestClass tc=new TestClass(); TestClass.InnerClass tci=tc.new InnerClass(); tci.id=999; tci.Innermethod1(); } public static void staticOtherMethod(){ System.out.println("其他类的静态方法"); new TestClass(); new TestClass().new InnerClass(); //相当于先new外部类,TestClass tc=new TestClass(); //在new内部类,TestClass.InnerClass tci=tc.new InnerClass(); TestClass tc=new TestClass(); TestClass.InnerClass tci=tc.new InnerClass(); tci.id=999; tci.Innermethod1(); } public OtherClass(){ System.out.println("其他类的构造方法"); new TestClass(); new TestClass().new InnerClass(); //相当于先new外部类,TestClass tc=new TestClass(); //在new内部类,TestClass.InnerClass tci=tc.new InnerClass(); TestClass tc=new TestClass(); TestClass.InnerClass tci=tc.new InnerClass(); tci.id=999; tci.Innermethod1(); // Innermethod1();不能省略 // id=999; } }
2.方法内部类
定义在方法中的类,相当于局部变量
基本格式:
1
2
3
4
5
6
7public class TestClass { public TestClass(){ //构造方法里面的内部类 class InnerClass{ } } }
2.1 方法内部类用法
(1)方法内部类(相当于局部变量),不能使用任何访问限制修饰符;
(2)方法内部类可以有实例变量/方法,构造方法,不能有静态元素;
(3)方法内部类可以访问本类的实例变量、实例方法、构造方法。【this/对象,也可以省略】;
(4)方法内部类可以访问本方法的局部变量,直接变量名称访问。
方法内部类访问本方法的局部变量时,方法内部类会默认是有final修饰符修饰本方法中的局部变量,final修饰的不能改值,局部变量也没有对象,不能创建对象。
(5)外部类是不能访问到方法内部类。
因为方法内部类相当于本方法中的局部变量,局部变量超出本方法访问不到。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72public class TestClass { int niu=222;//外部类实例变量 static String ok="hao";//外部类类变量 public TestClass(){ System.out.println("外部类的构造方法"); class InnerClass{ //构造方法里面的内部类 } } public void shiMethod(){ System.out.println("外部类的实例方法"); } public static void staticShiMethod(){ System.out.println("外部类的静态方法"); } public void TestClass1(){ int number=88;//本方法中的局部变量 //实例方法里面的内部类 class InnerClass{ int id=988;//实例变量 //static String name="hhh";报错 public void method1(){ System.out.println("方法内部类里面的实例方法"); new InnerClass(); new InnerClass().id=222; new InnerClass().method1(); new InnerClass("ddd"); this.id=33; this.method1(); id=33; method1(); //访问方法内部类外面的本方法中的局部变量 //this.number=999; 错误,局部变量默认是final修饰的,不能改值 //局部变量也没有对象,不能创建对象 //所以直接变量名称访问 System.out.println(number); } public InnerClass(){ System.out.println("方法内部类里面的构造方法1"); new InnerClass(); new InnerClass().id=222; new InnerClass().method1(); new InnerClass("ddd"); this.id=33; this.method1(); id=33; method1(); } public InnerClass(String name){ System.out.println("方法内部类里面的构造方法2"); } } } public static void TestClass2(){ //静态方法里面的内部类 class InnerClass{ //方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量 public void method1(){ new TestClass(); new TestClass().shiMethod(); new TestClass().niu=22; new TestClass().staticShiMethod(); new TestClass().ok="ss"; } } } }
3.静态嵌套类
相当于是java类中的静态变量
格式:
1
2
3
4public class TestClass { public static class InnerClass{ } }
(1)静态嵌套类中可以有构造方法,实例变量/方法,类变量/方法;
(2)静态嵌套类中构造方法/实例方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法;
(3)静态内部类中的类方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象】,类变量/方法;
(4)静态内部类中的构造方法/实例方法/类方法可以访问外部类的构造方法,实例变量/方法【只能对象】,类变量/方法;
(5)静态嵌套类中不能有this.
(6)外部类的构造方法/实例方法/类方法可以访问静态内部类中构造方法,实例变量/方法【只能对象】,类变量/方法;
(7)其他类中可以访问静态嵌套类【new外部类类名.静态嵌套类名()】。注意访问限制修饰符。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47public class TestClass { public static int id=5; public static int num=7; public void method1(){ } public static class InnerClass{ //静态内部类的实例变量 int id=23; //静态内部类的静态成员变量 static int num=20; //静态内部类的构造方法 public InnerClass(){ new InnerClass(); new InnerClass().id=1; new InnerClass().num=1; new InnerClass().method(); new InnerClass().staticMethod(); } //静态内部类的实例方法 public void method(){ new InnerClass(); new InnerClass().id=1; new InnerClass().num=1; new InnerClass().staticMethod(); } //静态内部类的静态方法 public static void staticMethod(){ new InnerClass(); new InnerClass().id=1; new InnerClass().num=1; new InnerClass().method(); new TestClass(); new TestClass().id=2; new TestClass().num=2; new TestClass().method1(); //this. } } } public class OtherClass { public void method(){ //其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】 new TestClass.InnerClass(); } }
4.匿名内部类
没有名字的java类,在不用创建出新类的情况下,构建出当前类的子类,构建的这个子类没有名字,所以叫匿名内部类。
基本格式:
1
2
3
4
5public class Person { public void method(){ System.out.println("person的方法"); } }
测试类:
1
2
3
4
5
6
7
8
9
10
11public class Main { public static void main(String[] args) { //不创建新类的情况下构建子类,叫匿名内部类 Person per=new Person(){ public void method(){ System.out.println("person的方法重写"); } }; per.method(); } }
上述蓝色标记就是匿名内部类,就相当于Person类的子类,只是没有名字。
4.1 继承式的匿名内部类
这个匿名内部类的作用是在不创建新类的情况下创建父类的子类,实现继承关系。
例:
1
2
3
4
5
6
7
8
9
10
11
12//抽象类 public abstract class Person { //抽象方法 public abstract void method(); } //普通类 public class PuTong{ //实例方法参数是抽象对象 public void method(Person per){ } }
测试类:
1
2
3
4
5
6
7
8
9
10
11
12public static void main(String[] args) { PuTong pt=new PuTong(); //pt.method(per);此处的per是抽象类,需要创建对象 //两种方式,上转型---子类对象赋值给父类对象 //Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类 Person per1=new Person(){ public void method() { } }; pt.method(per1); } }
4.2接口式的匿名内部类
这个匿名内部类的作用是在不创建新类的情况下创建接口的子类,实现多个接口。
当一个类中的方法参数是接口类型时,我们可以传递接口回调对象/子类对象,如果不想额外的创建一个接口的子类,这时我们使用匿名内部类也是可以的。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//接口 public interface TestInterface { //抽象方法 public abstract void method(); } //普通类 public class PuTong{ //实例方法参数是抽象对象 public void method(TestInterface tsi){ } } 测试类: public class Main { public static void main(String[] args) { PuTong pt=new PuTong(); //pt.method(tsi);此处的tsi是接口类,需要创建对象 //两种方式,接口回调对象---子类对象赋值给父类对象 //Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类 TestInterface tsi1=new TestInterface(){ public void method() { } }; pt.method(tsi1); } }
4.3 匿名内部类优缺点
优点:避免创建额外的独立子类。
缺点:不易理解,不易阅读。
最后
以上就是爱听歌大山最近收集整理的关于10.java内部类10.java内部类的全部内容,更多相关10内容请搜索靠谱客的其他文章。
发表评论 取消回复