Java内部类
Java内部类
内部类就是在类中再定义一个类,内部类可以用static、protected和private修饰(匿名内部类和局部内部类不能加修饰符,外部类只能用public和default修饰)。
内部类的一个典型用处:每个内部类都可以独立继承接口或类,并与外部类是否继承无关,相当于曲折地实现了多重继承。
虽然内部类和外部类在同一个源文件中,但是编译完成后在/bin下生成了两个.class文件,Outer.class和Outer$Inner.class(Outer代表外部类类名,Inner代表内部类类名)
根据位置不同,java的内部类分成四种:静态内部类、成员内部类、局部内部类、匿名内部类。
一、成员内部类
①成员内部类作为外部类的一个成员存在,与外部类的属性、方法并列,与外部类的实例变量有相同的作用域
②可以使用外部类所有的属性、方法
③成员内部类中,不能定义静态成员
④成员内部类中的属性和方法可以和外部类中的重名
(1)访问内部类自己的变量:直接使用变量名 或this.变量名
(2)访问外部类的变量: 外部类.this.变量名
1. package ex;
2. import ex.Outer.Inner;//这一行去掉会报错
3.
4. public class Test {
5. public static void main(String args[]) {
6. Outer outer = new Outer();
7. Inner inner = outer.new Inner(); //初始化
8. System.out.println(inner.getC());
9. }
10.
11. }
12.
13. class Outer{
14. private int priA = 1;
15. public int pubB = 2;
16. static final int staC = 3;
17. public Outer() {
18. System.out.println("In Outer");
19. }
20.
21. class Inner{
22. public Inner(){
23. System.out.println("In Inner");
24. }
25. public int getC()
26. {
27. return staC;
28. }
29. class Inner2{
30.
31. }
32. }
33.
34. }
35.
36. /*运行结果:
37. * In Outer
38. * In Inner
39. * 3
40. */
二、静态内部类(嵌套类)
如果一个类要被声明为static,只有一种情况,就是静态内部类。外部类是不能被static修饰的。
①静态内部类与静态变量类似,类加载以后存在
②静态内部类只能访问外部类的静态成员和方法(即使这些静态的方法和属性是private,也是可以访问的)
③静态内部类不依赖于外部类的实例,可以单独初始化
1. package ex;
2. import ex.Outer.Inner; //这一行去掉会报错
3. public class Test {
4. public static void main(String args[]) {
5. Inner inner = new Outer.Inner();
6. System.out.println(inner.getC());
7. }
8. }
9.
10. class Outer{
11. private int priA = 1;
12. public int pubB = 2;
13. static final int staC = 3;
14. public Outer() {
15. System.out.println("In Outer");
16. }
17.
18. public static class Inner{
19. public Inner(){
20. System.out.println("In Inner");
21. }
22. public int getC()
23. {
24. return staC;
25. }
26. class Inner2{
27.
28. }
29. }
30. }
31. /*运行结果:
32. * In Inner
33. * 3
34. */
三、匿名内部类
①匿名类是对原类的一个继承,同时创建了实例,{}花括号中就是继承了外部类之后的类体,类体中可以使用所有外部类的属性和方法.
②匿名类可以从抽象类或接口继承,但必须提供抽象方法的实现,可以覆盖原有方法,不可以写入新方法
③匿名类永远不能是抽象的。
④匿名类总是隐式的final。
⑤匿名类总是一个内部类,并且不能是static的。
⑥匿名内部类中是不能定义构造函数的,自动调用父类的构造函数
⑦匿名类不能有显式声明的构造函数。相反的,Java编译器必须为这个匿名类自动提供一个匿名构造函数。
1. package ex;
2.
3. public class Test {
4. public static void main(String args[]) {
5. Outer outer = new Outer() {
6. public void show() {
7. System.out.println(a);
8. }
9. };
10. outer.show();
11. }
12. }
13.
14. class Outer{
15. protected int a = 20;
16. public void show() {
17. }
18. }
19. /*运行结果:
20. * 20
21. */
四、局部内部类
在方法中定义的内部类称为局部内部类
①局部变量相似,局部内部类不能有访问说明符。
②局部内部类不是外部类的一部分,但它可以访问当前代码块内的常量和此外围类的所有成员。
③不可以定义静态变量和方法
1. package ex;
2. import java.lang.Integer;
3.
4. public class Test {
5. public static void main(String args[]) {
6. Outer outer = new Outer();
7. outer.show();
8. }
9. }
10.
11. class Outer{
12. private int priA = 1;
13. public int pubB = 2;
14. static final int staC = 3;
15. public Outer() {
16. //System.out.println("In Outer");
17. }
18. public void show() {
19. final int a = 5;
20. int b = 3;
21. Integer ba = new Integer(3);
22. class Inner { //类前不能有访问说明符
23. public void present() { //可以访问当前代码块内的常量和此外围类的所有成员
24. System.out.println("Inner:");
25. System.out.println("当前方法show中的常量a: " + a);
26. System.out.println("当前方法show中的变量b: " + b); //这边很有意思,下面贴了两张图
27. System.out.println("当前方法show中的变量ba: " + ba);
28. System.out.println("Outer中的A、B、C:" + priA + " " + pubB + " " +staC);
29. }
30. //不可以定义静态变量和方法
31. //static int m = 5;
32. }
33. Inner inner = new Inner();
34. inner.present();
35. }
36. }
37. /*运行结果:
38. * Inner:
39. * 当前方法show中的常量a: 5
40. * 当前方法show中的变量b: 3
41. * Outer中的A、B、C:1 2 3
42. */
a的值改动之后在Inner里调用变量a时报错了
//如有错误欢迎指正