Java的内部类学习
1.匿名内部类
匿名类是不能有名称的类,所以没办法引用它们。必须在创建时,作为new语句的一部分来声明它们。这就要采用另一种形式的new语句,如下所示: new <类或接口> <类的主体> 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。它还创建那个类的一个新实例,并把它作为语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数,后跟匿名类的主体。如果匿名类对另一个类进行扩展,它的主体可以访问类的成员、覆盖它的方法等等,这和其他任何标准的类都是一样的。如果匿名类实现了一个接口,它的主体必须实现接口的方法。
匿名内部类的注意事项
注意匿名类的声明是在编译时进行的,实例化在运行时进行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
在使用匿名内部类时,要记住以下几个原则:
·匿名内部类不能有构造方法。
·匿名内部类不能定义任何静态成员、方法和类。
·匿名内部类不能是public,protected,private,static。
·只能创建匿名内部类的一个实例。
·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
·内部类只能访问外部类的静态变量或静态方法。
1 2 interface NoNameClass { 3 4 void print(); 5 6 } 7 8 9 class NoInnerClass { 10 11 12 public NoNameClass show() { 13 14 return new NoNameClass() { 15 16 17 @Override 18 19 public void print() { 20 21 System.out.println("hello world"); 22 23 } 24 25 }; 26 27 } 28 29 } 30 31 32 public class NoNameInnerClass { 33 34 public static void main(String[] args) { 35 36 NoInnerClass innerClass = new NoInnerClass(); 37 38 innerClass.show().print(); 39 40 } 41 42 }
2.静态内部类(嵌套类)(只有内部类才能定义为staticclass)
静态内部类只能调用外部类的静态变量和静态方法
静态内部类中可以定义静态或者非静态的成员
1 class InnerClass { 2 3 private static int a=7; 4 5 public static void show() 6 7 { 8 9 System.out.println("show"); 10 11 } 12 13 public static class staticInner{ 14 15 16 public void info() 17 18 { 19 20 System.out.println(a); 21 22 show(); 23 24 } 25 26 } 27 28 } 29 30 31 public class InnerClassTest 32 33 { 34 35 public static void main(String[] args) { 36 37 InnerClass.staticInner innerClass=new InnerClass.staticInner(); 38 39 innerClass.info(); 40 41 } 42 43 }
3.局部内部类
成员内部类可以调用外部类的静态和非静态变量和方法
但是成员内部类内部不能定义static 方法
1 class LocalClass { 2 3 private int a = 1; 4 5 private static int b = 2; 6 7 void info() { 8 9 final int c = 4; 10 11 class Inner { 12 13 int a = 3; 14 15 16 void print() { 17 18 System.out.println(a);// 内部类的变量 19 20 System.out.println(LocalClass.this.a);// 外部类变量 21 22 System.out.println(b);// 外部类的静态变量 23 24 System.out.println(c);// 只能访问方法内部的final变量 25 26 } 27 28 } 29 30 new Inner().print(); 31 32 } 33 34 } 35 36 37 public class LocalInnerClass { 38 39 public static void main(String[] args) { 40 41 newLocalClass().info(); 42 43 } 44 45 }
4.成员内部类
成员内部类可以调用外部类的静态和非静态变量和方法
但是成员内部类内部不能定义static 方法
class MemberClass { private int a = 2; private static int b = 3; private static void show() { System.out.println("show"); } class InnerMember { private int a = 45; void info() { System.out.println(b); System.out.println(a);//就近原则,a为当前作用域内的变量得不到外部类的a System.out.println(MemberClass.this.a);//这样可以访问外部类的重名变量 show(); } } } public class MemberInnerClass { public static void main(String[] args) { MemberClass.InnerMember innerMember = new MemberClass().new InnerMember();//有人会疑惑为什么和静态内部类实例化的时候不一样呢 //这是因为静态内部类就像静态方法一样是属于类的,而成员内部类是属于对象的,所以要 new MemberClass().new InnerMember()得到每个对象关于innerMember的实例对象 innerMember.info(); } }